public void RazorPageDocumentClassifierPass_UsesRelativePathToGenerateTypeName(string relativePath, string expected)
        {
            // Arrange
            var properties   = new RazorSourceDocumentProperties(filePath: "ignored", relativePath: relativePath);
            var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create("@page", properties));

            var engine     = CreateEngine();
            var irDocument = CreateIRDocument(engine, codeDocument);
            var pass       = new RazorPageDocumentClassifierPass
            {
                Engine = engine
            };

            // Act
            pass.Execute(codeDocument, irDocument);
            var visitor = new Visitor();

            visitor.Visit(irDocument);

            // Assert
            Assert.Equal(expected, visitor.Class.ClassName);
        }
예제 #2
0
        public static IList <RazorPageGeneratorResult> MainCore(RazorEngine razorEngine, string targetProjectDirectory)
        {
            var viewDirectories = Directory.EnumerateDirectories(targetProjectDirectory, "Views", SearchOption.AllDirectories);
            var razorProject    = RazorProject.Create(targetProjectDirectory);
            var templateEngine  = new RazorTemplateEngine(razorEngine, razorProject);

            templateEngine.Options.DefaultImports = RazorSourceDocument.Create(@"
@using System
@using System.Threading.Tasks
", fileName: null);

            var fileCount = 0;

            var results = new List <RazorPageGeneratorResult>();

            foreach (var viewDir in viewDirectories)
            {
                Console.WriteLine();
                Console.WriteLine("  Generating code files for views in {0}", viewDir);
                var viewDirPath = viewDir.Substring(targetProjectDirectory.Length).Replace('\\', '/');
                var cshtmlFiles = razorProject.EnumerateItems(viewDirPath);

                if (!cshtmlFiles.Any())
                {
                    Console.WriteLine("  No .cshtml files were found.");
                    continue;
                }

                foreach (var item in cshtmlFiles)
                {
                    Console.WriteLine("    Generating code file for view {0}...", item.FileName);
                    results.Add(GenerateCodeFile(templateEngine, item));
                    Console.WriteLine("      Done!");
                    fileCount++;
                }
            }

            return(results);
        }
예제 #3
0
    public void RazorPageDocumentClassifierPass_SanitizesClassName()
    {
        // Arrange
        var properties   = new RazorSourceDocumentProperties(filePath: @"x:\Test.cshtml", relativePath: "path.with+invalid-chars");
        var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create("@page", properties));

        var engine     = CreateProjectEngine().Engine;
        var irDocument = CreateIRDocument(engine, codeDocument);
        var pass       = new RazorPageDocumentClassifierPass
        {
            Engine = engine
        };

        // Act
        pass.Execute(codeDocument, irDocument);
        var visitor = new Visitor();

        visitor.Visit(irDocument);

        // Assert
        Assert.Equal("path_with_invalid_chars", visitor.Class.ClassName);
    }
예제 #4
0
    public void RazorPageDocumentClassifierPass_UsesAbsolutePath_IfRelativePathIsNotSet()
    {
        // Arrange
        var properties   = new RazorSourceDocumentProperties(filePath: @"x::\application\Views\Home\Index.cshtml", relativePath: null);
        var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create("@page", properties));

        var engine     = CreateProjectEngine().Engine;
        var irDocument = CreateIRDocument(engine, codeDocument);
        var pass       = new RazorPageDocumentClassifierPass
        {
            Engine = engine
        };

        // Act
        pass.Execute(codeDocument, irDocument);
        var visitor = new Visitor();

        visitor.Visit(irDocument);

        // Assert
        Assert.Equal("x___application_Views_Home_Index", visitor.Class.ClassName);
    }
예제 #5
0
        public void GetCompilationFailedResult_WithMissingReferences()
        {
            // Arrange
            var expected    = "One or more compilation references may be missing. If you're seeing this in a published application, set 'CopyRefAssembliesToPublishDirectory' to true in your project file to ensure files in the refs directory are published.";
            var compilation = CSharpCompilation.Create("Test", options: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary));
            var syntaxTree  = CSharpSyntaxTree.ParseText("@class Test { public string Test { get; set; } }");

            compilation = compilation.AddSyntaxTrees(syntaxTree);
            var emitResult = compilation.Emit(new MemoryStream());

            // Act
            var exception = CompilationFailedExceptionFactory.Create(
                RazorCodeDocument.Create(RazorSourceDocument.Create("Test", "Index.cshtml"), Enumerable.Empty <RazorSourceDocument>()),
                syntaxTree.ToString(),
                "Test",
                emitResult.Diagnostics);

            // Assert
            Assert.Collection(
                exception.CompilationFailures,
                failure => Assert.Equal(expected, failure.FailureSummary));
        }
예제 #6
0
        private string Generate(
            Type templateBaseType,
            string template)
        {
            var engine = RazorProjectEngine.Create(
                RazorConfiguration.Default,
                RazorProjectFileSystem.Create(@"."),
                builder =>
            {
                builder.SetNamespace(templateBaseType.Namespace);
                builder.SetBaseType(Regex.Replace(templateBaseType.ToString(), @"`\d+\[", "<").Replace(']', '>'));
            });

            var document = RazorSourceDocument.Create(template, Path.GetRandomFileName());

            var codeDocument = engine.Process(
                document,
                null,
                new List <RazorSourceDocument>(),
                new List <TagHelperDescriptor>());

            return(codeDocument.GetCSharpDocument().GeneratedCode);
        }
예제 #7
0
        public void MvcViewDocumentClassifierPass_SetsUpExecuteAsyncMethod()
        {
            // Arrange
            var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create("some-content", "Test.cshtml"));

            var projectEngine = CreateProjectEngine();
            var irDocument    = CreateIRDocument(projectEngine, codeDocument);
            var pass          = new MvcViewDocumentClassifierPass
            {
                Engine = projectEngine.Engine
            };

            // Act
            pass.Execute(codeDocument, irDocument);
            var visitor = new Visitor();

            visitor.Visit(irDocument);

            // Assert
            Assert.Equal("ExecuteAsync", visitor.Method.MethodName);
            Assert.Equal("global::System.Threading.Tasks.Task", visitor.Method.ReturnType);
            Assert.Equal(new[] { "public", "async", "override" }, visitor.Method.Modifiers);
        }
예제 #8
0
        public void ConsolidatedMvcViewDocumentClassifierPass_UsesRelativePathToGenerateTypeName(string relativePath, string expected)
        {
            // Arrange
            var properties   = new RazorSourceDocumentProperties(filePath: "ignored", relativePath: relativePath);
            var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create("some-content", properties));

            var projectEngine = CreateProjectEngine();
            var irDocument    = CreateIRDocument(projectEngine, codeDocument);
            var pass          = new MvcViewDocumentClassifierPass(useConsolidatedMvcViews: true)
            {
                Engine = projectEngine.Engine
            };

            // Act
            pass.Execute(codeDocument, irDocument);
            var visitor = new Visitor();

            visitor.Visit(irDocument);

            // Assert
            Assert.Equal(expected, visitor.Class.ClassName);
            Assert.Equal(new[] { "internal", "sealed" }, visitor.Class.Modifiers);
        }
예제 #9
0
        // Internal for testing
        internal void AddHierarchicalImports(string sourceFilePath, List <RazorSourceDocument> imports)
        {
            // We want items in descending order. FindHierarchicalItems returns items in ascending order.
            var importProjectItems = ProjectEngine.FileSystem.FindHierarchicalItems(sourceFilePath, ImportsFileName).Reverse();

            foreach (var importProjectItem in importProjectItems)
            {
                RazorSourceDocument importSourceDocument;

                if (importProjectItem.Exists)
                {
                    importSourceDocument = RazorSourceDocument.ReadFrom(importProjectItem);
                }
                else
                {
                    // File doesn't exist on disk so just add a marker source document as an identifier for "there could be something here".
                    var sourceDocumentProperties = new RazorSourceDocumentProperties(importProjectItem.FilePath, importProjectItem.RelativePhysicalPath);
                    importSourceDocument = RazorSourceDocument.Create(string.Empty, sourceDocumentProperties);
                }

                imports.Add(importSourceDocument);
            }
        }
        private CompletionList GenerateCompletionList(string documentContent, int queryIndex, TagHelperCompletionProvider componentCompletionProvider)
        {
            var sourceDocument           = RazorSourceDocument.Create(documentContent, RazorSourceDocumentProperties.Default);
            var syntaxTree               = RazorSyntaxTree.Parse(sourceDocument);
            var tagHelperDocumentContext = TagHelperDocumentContext.Create(prefix: string.Empty, DefaultTagHelpers);

            var completionQueryLocation = new SourceSpan(queryIndex, length: 0);
            var razorCompletionItems    = componentCompletionProvider.GetCompletionItems(syntaxTree, tagHelperDocumentContext, completionQueryLocation);
            var completionList          = RazorCompletionEndpoint.CreateLSPCompletionList(
                razorCompletionItems,
                new CompletionListCache(),
                new[] { ExtendedCompletionItemKinds.TagHelper },
                new PlatformAgnosticCompletionCapability()
            {
                VSCompletionList = new VSCompletionListCapability()
                {
                    CommitCharacters = true,
                    Data             = true,
                }
            });

            return(completionList);
        }
예제 #11
0
        public void RazorPageDocumentClassifierPass_LogsErrorIfDirectiveNotAtTopOfFile()
        {
            // Arrange
            var sourceSpan = new SourceSpan(
                "Test.cshtml",
                absoluteIndex: 14 + Environment.NewLine.Length * 2,
                lineIndex: 2,
                characterIndex: 0,
                length: 5 + Environment.NewLine.Length);

            var expectedDiagnostic = RazorExtensionsDiagnosticFactory.CreatePageDirective_MustExistAtTheTopOfFile(sourceSpan);
            var content            = @"
@somethingelse
@page
";
            var codeDocument       = RazorCodeDocument.Create(RazorSourceDocument.Create(content, "Test.cshtml"));

            var engine     = CreateRuntimeEngine();
            var irDocument = CreateIRDocument(engine, codeDocument);
            var pass       = new RazorPageDocumentClassifierPass
            {
                Engine = engine
            };

            // Act
            pass.Execute(codeDocument, irDocument);
            var visitor = new Visitor();

            visitor.Visit(irDocument);

            // Assert
            var pageDirectives = irDocument.FindDirectiveReferences(PageDirective.Directive);
            var directive      = Assert.Single(pageDirectives);
            var diagnostic     = Assert.Single(directive.Node.Diagnostics);

            Assert.Equal(expectedDiagnostic, diagnostic);
        }
예제 #12
0
        public void MvcViewDocumentClassifierPass_NullFilePath_SetsClass()
        {
            // Arrange
            var properties   = new RazorSourceDocumentProperties(filePath: null, relativePath: null);
            var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create("some-content", properties));

            var projectEngine = CreateProjectEngine();
            var irDocument    = CreateIRDocument(projectEngine, codeDocument);
            var pass          = new MvcViewDocumentClassifierPass
            {
                Engine = projectEngine.Engine
            };

            // Act
            pass.Execute(codeDocument, irDocument);
            var visitor = new Visitor();

            visitor.Visit(irDocument);

            // Assert
            Assert.Equal("global::Microsoft.AspNetCore.Mvc.Razor.RazorPage<TModel>", visitor.Class.BaseType);
            Assert.Equal(new[] { "public" }, visitor.Class.Modifiers);
            Assert.Equal("AspNetCore_d9f877a857a7e9928eac04d09a59f25967624155", visitor.Class.ClassName);
        }
예제 #13
0
        public void RazorPageDocumentClassifierPass_NullFilePath_SetsClass()
        {
            // Arrange
            var properties   = new RazorSourceDocumentProperties(filePath: null, relativePath: null);
            var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create("@page", properties));

            var engine     = CreateProjectEngine().Engine;
            var irDocument = CreateIRDocument(engine, codeDocument);
            var pass       = new RazorPageDocumentClassifierPass
            {
                Engine = engine
            };

            // Act
            pass.Execute(codeDocument, irDocument);
            var visitor = new Visitor();

            visitor.Visit(irDocument);

            // Assert
            Assert.Equal("global::Microsoft.AspNetCore.Mvc.RazorPages.Page", visitor.Class.BaseType);
            Assert.Equal(new[] { "public" }, visitor.Class.Modifiers);
            Assert.Equal("AspNetCore_74fbaab062bb228ed1ab09c5ff8d6ed2417320e2", visitor.Class.ClassName);
        }
예제 #14
0
        public void MvcViewDocumentClassifierPass_SetsClass()
        {
            // Arrange
            var properties   = new RazorSourceDocumentProperties(filePath: "ignored", relativePath: "Test.cshtml");
            var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create("some-content", properties));

            var projectEngine = CreateProjectEngine();
            var irDocument    = CreateIRDocument(projectEngine, codeDocument);
            var pass          = new MvcViewDocumentClassifierPass
            {
                Engine = projectEngine.Engine
            };

            // Act
            pass.Execute(codeDocument, irDocument);
            var visitor = new Visitor();

            visitor.Visit(irDocument);

            // Assert
            Assert.Equal("global::Microsoft.AspNetCore.Mvc.Razor.RazorPage<TModel>", visitor.Class.BaseType);
            Assert.Equal(new[] { "public" }, visitor.Class.Modifiers);
            Assert.Equal("Test", visitor.Class.ClassName);
        }
예제 #15
0
        public void ComponentDocumentClassifierPass_SanitizesClassName()
        {
            // Arrange
            var properties   = new RazorSourceDocumentProperties(filePath: @"x:\path.with+invalid-chars.razor", relativePath: "path.with+invalid-chars.razor");
            var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create("some-content", properties));

            codeDocument.SetFileKind(FileKinds.Component);

            var projectEngine = CreateProjectEngine();
            var irDocument    = CreateIRDocument(projectEngine, codeDocument);
            var pass          = new ComponentDocumentClassifierPass
            {
                Engine = projectEngine.Engine
            };

            // Act
            pass.Execute(codeDocument, irDocument);
            var visitor = new Visitor();

            visitor.Visit(irDocument);

            // Assert
            Assert.Equal("path_with_invalid_chars", visitor.Class.ClassName);
        }
예제 #16
0
        public void ComponentDocumentClassifierPass_SetsNamespace()
        {
            // Arrange
            var properties   = new RazorSourceDocumentProperties(filePath: "/MyApp/Test.razor", relativePath: "Test.razor");
            var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create("some-content", properties));

            codeDocument.SetFileKind(FileKinds.Component);

            var projectEngine = CreateProjectEngine();
            var irDocument    = CreateIRDocument(projectEngine, codeDocument);
            var pass          = new ComponentDocumentClassifierPass
            {
                Engine = projectEngine.Engine
            };

            // Act
            pass.Execute(codeDocument, irDocument);
            var visitor = new Visitor();

            visitor.Visit(irDocument);

            // Assert
            Assert.Equal("MyApp", visitor.Namespace.Content);
        }
예제 #17
0
        private string GetGeneratorResultBak(IEnumerable <string> namespaces, TypeContext context)
        {
#pragma warning disable 612, 618
            var razorCompiledItemAssembly = typeof(RazorCompiledItemAttribute).Assembly;
            //手动加载程序集,防止编译 Razor 类时找不到 DLL
            var razorEngine = RazorEngine.Create(builder =>
            {
                InheritsDirective.Register(builder);
                FunctionsDirective.Register(builder);
                SectionDirective.Register(builder);
                builder
                .SetNamespace(DynamicTemplateNamespace)
                //.SetBaseType("Microsoft.Extensions.RazorViews.BaseView")
                .SetBaseType(BuildTypeName(context.TemplateType, context.ModelType))
                .ConfigureClass((document, @class) =>
                {
                    @class.ClassName = context.ClassName;
                    //if (!str  ing.IsNullOrWhiteSpace(document.Source.FilePath))
                    //{
                    //    @class.ClassName = Path.GetFileNameWithoutExtension(document.Source.FilePath);
                    //}
                    @class.Modifiers.Clear();
                    @class.Modifiers.Add("internal");
                });
                builder.Features.Add(new SuppressChecksumOptionsFeature());
            });

            string importString = @"
@using System
@using System.Threading.Tasks
";
            importString += String.Join("\r\n", namespaces.Select(n => "@using " + n.Trim())) + "\r\n";

            using (var reader = context.TemplateContent.GetTemplateReader())
            {
                string path = null;
                if (string.IsNullOrWhiteSpace(context.TemplateContent.TemplateFile))
                {
                    path = Directory.GetCurrentDirectory();
                }
                else
                {
                    path = Path.GetDirectoryName(context.TemplateContent.TemplateFile);
                }
                var razorProject   = RazorProjectFileSystem.Create(path);
                var templateEngine = new RazorTemplateEngine(razorEngine, razorProject);
                templateEngine.Options.DefaultImports = RazorSourceDocument.Create(importString, fileName: null);
                RazorPageGeneratorResult result;
                if (string.IsNullOrWhiteSpace(context.TemplateContent.TemplateFile))
                {
                    var item    = RazorSourceDocument.Create(context.TemplateContent.Template, string.Empty);
                    var imports = new List <RazorSourceDocument>();
                    imports.Add(templateEngine.Options.DefaultImports);
                    var doc = RazorCodeDocument.Create(item, imports);
                    result = GenerateCodeFile(templateEngine, doc);
                }
                else
                {
                    var item = razorProject.GetItem(context.TemplateContent.TemplateFile);
                    result = GenerateCodeFile(templateEngine, item);
                }
                return(InspectSource(result, context));
            }
        }
예제 #18
0
        private MemoryStream CreateAndCompileToStream(string templateSource, params Assembly[] linkedAssemblies)
        {
            RazorProjectEngine engine = RazorProjectEngine.Create(
                RazorConfiguration.Default,
                RazorProjectFileSystem.Create(@"."),
                (builder) =>
            {
                builder.SetNamespace("TemplateNamespace");
            });

            string fileName = Path.GetRandomFileName();

            RazorSourceDocument document = RazorSourceDocument.Create(templateSource, fileName);

            RazorCodeDocument codeDocument = engine.Process(
                document,
                null,
                new List <RazorSourceDocument>(),
                new List <TagHelperDescriptor>());

            RazorCSharpDocument razorCSharpDocument = codeDocument.GetCSharpDocument();

            List <PortableExecutableReference> portableExecutableReferences = new List <PortableExecutableReference>
            {
                MetadataReference.CreateFromFile(typeof(object).Assembly.Location),
                MetadataReference.CreateFromFile(Assembly.Load(new AssemblyName("Microsoft.CSharp")).Location),
                MetadataReference.CreateFromFile(typeof(RazorEngineTemplateBase).Assembly.Location),
                MetadataReference.CreateFromFile(typeof(ExpandoObject).Assembly.Location),
                MetadataReference.CreateFromFile(Assembly.Load(new AssemblyName("netstandard")).Location),
                MetadataReference.CreateFromFile(Assembly.Load(new AssemblyName("System.Runtime")).Location),
            };

            foreach (Assembly assembly in linkedAssemblies)
            {
                portableExecutableReferences.Add(MetadataReference.CreateFromFile(assembly.Location));
            }

            CSharpCompilation compilation = CSharpCompilation.Create(
                fileName,
                new[]
            {
                CSharpSyntaxTree.ParseText(razorCSharpDocument.GeneratedCode)
            },
                portableExecutableReferences,
                new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary));

            MemoryStream memoryStream = new MemoryStream();

            EmitResult emitResult = compilation.Emit(memoryStream);

            if (!emitResult.Success)
            {
                List <Diagnostic> errors = emitResult.Diagnostics.ToList();

                RazorEngineCompilationException exception = new RazorEngineCompilationException("Unable to compile template: " + errors.FirstOrDefault()?.ToString());
                exception.Errors = errors;

                throw exception;
            }

            memoryStream.Position = 0;
            return(memoryStream);
        }
        protected override async Task <TemplateResult> ProcessSingleTemplate(string content,
                                                                             dynamic templateModel)
        {
            var razorEngine = RazorEngine.Create((builder) =>
            {
                RazorExtensions.Register(builder);
            });

            // Don't care about the RazorProject as we already have the content of the .cshtml file
            // and don't need to deal with imports.
            var razorProject        = RazorProject.Create(Directory.GetCurrentDirectory());
            var razorTemplateEngine = new RazorTemplateEngine(razorEngine, razorProject);

            var imports = new RazorSourceDocument[]
            {
                RazorSourceDocument.Create(@"
@using System
@using System.Threading.Tasks
", fileName: null)
            };

            var razorDocument    = RazorCodeDocument.Create(RazorSourceDocument.Create(content, "Template"), imports);
            var generatorResults = razorTemplateEngine.GenerateCode(razorDocument);

            if (generatorResults.Diagnostics.Any())
            {
                var messages = generatorResults.Diagnostics.Select(d => d.GetMessage());
                return(new TemplateResult()
                {
                    GeneratedText = string.Empty,
                    ProcessingException = new TemplateProcessingException(messages, generatorResults.GeneratedCode)
                });
            }
            var templateResult = _compilationService.Compile(generatorResults.GeneratedCode);

            if (templateResult.Messages.Any())
            {
                return(new TemplateResult()
                {
                    GeneratedText = string.Empty,
                    ProcessingException = new TemplateProcessingException(templateResult.Messages, generatorResults.GeneratedCode)
                });
            }

            var compiledObject = Activator.CreateInstance(templateResult.CompiledType);
            var razorTemplate  = compiledObject as RazorTemplateBase;

            string result = String.Empty;

            if (razorTemplate != null)
            {
                razorTemplate.Model = templateModel;
                //ToDo: If there are errors executing the code, they are missed here.
                result = await razorTemplate.ExecuteTemplate();
            }

            return(new TemplateResult()
            {
                GeneratedText = result,
                ProcessingException = null
            });
        }
예제 #20
0
        public void GetCompilationFailedResult_ReturnsCompilationResult_WithGroupedMessages()
        {
            // Arrange
            var viewPath = "Views/Home/Index";
            var generatedCodeFileName = "Generated Code";
            var codeDocument          = RazorCodeDocument.Create(RazorSourceDocument.Create("view-content", viewPath));
            var assemblyName          = "random-assembly-name";

            var diagnostics = new[]
            {
                Diagnostic.Create(
                    GetRoslynDiagnostic("message-1"),
                    Location.Create(
                        viewPath,
                        new TextSpan(10, 5),
                        new LinePositionSpan(new LinePosition(10, 1), new LinePosition(10, 2)))),
                Diagnostic.Create(
                    GetRoslynDiagnostic("message-2"),
                    Location.Create(
                        assemblyName,
                        new TextSpan(1, 6),
                        new LinePositionSpan(new LinePosition(1, 2), new LinePosition(3, 4)))),
                Diagnostic.Create(
                    GetRoslynDiagnostic("message-3"),
                    Location.Create(
                        viewPath,
                        new TextSpan(40, 50),
                        new LinePositionSpan(new LinePosition(30, 5), new LinePosition(40, 12)))),
            };

            // Act
            var compilationResult = CompilationFailedExceptionFactory.Create(
                codeDocument,
                "compilation-content",
                assemblyName,
                diagnostics);

            // Assert
            Assert.Collection(compilationResult.CompilationFailures,
                              failure =>
            {
                Assert.Equal(viewPath, failure.SourceFilePath);
                Assert.Equal("view-content", failure.SourceFileContent);
                Assert.Collection(failure.Messages,
                                  message =>
                {
                    Assert.Equal("message-1", message.Message);
                    Assert.Equal(viewPath, message.SourceFilePath);
                    Assert.Equal(11, message.StartLine);
                    Assert.Equal(2, message.StartColumn);
                    Assert.Equal(11, message.EndLine);
                    Assert.Equal(3, message.EndColumn);
                },
                                  message =>
                {
                    Assert.Equal("message-3", message.Message);
                    Assert.Equal(viewPath, message.SourceFilePath);
                    Assert.Equal(31, message.StartLine);
                    Assert.Equal(6, message.StartColumn);
                    Assert.Equal(41, message.EndLine);
                    Assert.Equal(13, message.EndColumn);
                });
            },
                              failure =>
            {
                Assert.Equal(generatedCodeFileName, failure.SourceFilePath);
                Assert.Equal("compilation-content", failure.SourceFileContent);
                Assert.Collection(failure.Messages,
                                  message =>
                {
                    Assert.Equal("message-2", message.Message);
                    Assert.Equal(assemblyName, message.SourceFilePath);
                    Assert.Equal(2, message.StartLine);
                    Assert.Equal(3, message.StartColumn);
                    Assert.Equal(4, message.EndLine);
                    Assert.Equal(5, message.EndColumn);
                });
            });
        }
예제 #21
0
        private MemoryStream CreateAndCompileToStream(string templateSource, RazorEngineCompilationOptions options)
        {
            templateSource = this.WriteDirectives(templateSource, options);

            RazorProjectEngine engine = RazorProjectEngine.Create(
                RazorConfiguration.Default,
                RazorProjectFileSystem.Create(@"."),
                (builder) =>
            {
                builder.SetNamespace(options.TemplateNamespace);
            });

            string fileName = Path.GetRandomFileName();

            RazorSourceDocument document = RazorSourceDocument.Create(templateSource, fileName);

            RazorCodeDocument codeDocument = engine.Process(
                document,
                null,
                new List <RazorSourceDocument>(),
                new List <TagHelperDescriptor>());

            RazorCSharpDocument razorCSharpDocument = codeDocument.GetCSharpDocument();

            SyntaxTree syntaxTree = CSharpSyntaxTree.ParseText(razorCSharpDocument.GeneratedCode);

            CSharpCompilation compilation = CSharpCompilation.Create(
                fileName,
                new[]
            {
                syntaxTree
            },
                options.ReferencedAssemblies
                .Select(ass =>
            {
#if NETSTANDARD2_0
                return(MetadataReference.CreateFromFile(ass.Location));
#else
                unsafe
                {
                    ass.TryGetRawMetadata(out byte *blob, out int length);
                    ModuleMetadata moduleMetadata                 = ModuleMetadata.CreateFromMetadata((IntPtr)blob, length);
                    AssemblyMetadata assemblyMetadata             = AssemblyMetadata.Create(moduleMetadata);
                    PortableExecutableReference metadataReference = assemblyMetadata.GetReference();

                    return(metadataReference);
                }
#endif
            })
                .Concat(options.MetadataReferences)
                .ToList(),
                new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary));

            MemoryStream memoryStream = new MemoryStream();

            EmitResult emitResult = compilation.Emit(memoryStream);

            if (!emitResult.Success)
            {
                RazorEngineCompilationException exception = new RazorEngineCompilationException()
                {
                    Errors        = emitResult.Diagnostics.ToList(),
                    GeneratedCode = razorCSharpDocument.GeneratedCode
                };

                throw exception;
            }

            memoryStream.Position = 0;

            return(memoryStream);
        }
예제 #22
0
        private RazorCodeDocument CreateDocument(string content)
        {
            var source = RazorSourceDocument.Create(content, "test.cshtml");

            return(ProjectEngine.CreateCodeDocumentCore(source, FileKinds.Component));
        }
예제 #23
0
파일: ViewEngine.cs 프로젝트: lht6/Furion
        /// <summary>
        /// 将模板内容编译并输出内存流
        /// </summary>
        /// <param name="templateSource"></param>
        /// <param name="options"></param>
        /// <returns></returns>
        private static MemoryStream CreateAndCompileToStream(string templateSource, ViewEngineOptions options)
        {
            templateSource = WriteDirectives(templateSource, options);

            var engine = RazorProjectEngine.Create(
                RazorConfiguration.Default,
                RazorProjectFileSystem.Create(@"."),
                (builder) =>
            {
                builder.SetNamespace(options.TemplateNamespace);
            });

            var fileName = Path.GetRandomFileName();

            var document = RazorSourceDocument.Create(templateSource, fileName);

            var codeDocument = engine.Process(
                document,
                null,
                new List <RazorSourceDocument>(),
                new List <TagHelperDescriptor>());

            var razorCSharpDocument = codeDocument.GetCSharpDocument();

            var syntaxTree = CSharpSyntaxTree.ParseText(razorCSharpDocument.GeneratedCode);

            var compilation = CSharpCompilation.Create(
                fileName,
                new[]
            {
                syntaxTree
            },
                options.ReferencedAssemblies
                .Select(ass =>
            {
                // MetadataReference.CreateFromFile(ass.Location)

                unsafe
                {
                    ass.TryGetRawMetadata(out var blob, out var length);
                    var moduleMetadata    = ModuleMetadata.CreateFromMetadata((IntPtr)blob, length);
                    var assemblyMetadata  = AssemblyMetadata.Create(moduleMetadata);
                    var metadataReference = assemblyMetadata.GetReference();
                    return(metadataReference);
                }
            })
                .Concat(options.MetadataReferences)
                .ToList(),
                new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary));

            var memoryStream = new MemoryStream();

            var emitResult = compilation.Emit(memoryStream);

            if (!emitResult.Success)
            {
                var errors = emitResult.Diagnostics.ToList();

                var exception = new ViewEngineTemplateException($"Unable to compile template: {errors.FirstOrDefault()}")
                {
                    Errors        = errors,
                    GeneratedCode = razorCSharpDocument.GeneratedCode
                };

                throw exception;
            }

            memoryStream.Position = 0;

            return(memoryStream);
        }
예제 #24
0
    private RazorCodeDocument CreateDocument(string content)
    {
        var source = RazorSourceDocument.Create(content, "test.cshtml");

        return(RazorCodeDocument.Create(source));
    }
예제 #25
0
        private static Type CreateGeneratorType(Type _)
        {
            var name = typeof(T).FullName;

            var metadataReferences = GetMetadataReferences();

            RazorSourceDocument document;

            using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream($"{name}.razor"))
            {
                if (stream == null)
                {
                    throw new Exception($"Could not find embedded resource {name}.razor");
                }
                using (var reader = new StreamReader(stream))
                {
                    document = RazorSourceDocument.Create(reader.ReadToEnd(), $"{name}.razor");
                }
            }

#pragma warning disable CS0618 //Create and Register are marked as obsolete but there aren't alternative available
            var engine = RazorEngine.Create(b =>
            {
                FunctionsDirective.Register(b);
                InheritsDirective.Register(b);
#pragma warning restore CS0618
            });
            RazorCodeDocument codeDocument = RazorCodeDocument.Create(document);
            engine.Process(codeDocument);
            string code;
            using (var srcFileWriter = new StringWriter())
            {
                code = codeDocument.GetCSharpDocument().GeneratedCode;
            }

            SourceText sourceText = SourceText.From(code, Encoding.UTF8);
            SyntaxTree syntaxTree = CSharpSyntaxTree.ParseText(sourceText, CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.Latest));
            CSharpCompilationOptions compilationOptions = new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)
                                                          .WithSpecificDiagnosticOptions(new Dictionary <string, ReportDiagnostic> {
                // Binding redirects
                ["CS1701"] = ReportDiagnostic.Suppress,
                ["CS1702"] = ReportDiagnostic.Suppress,
                ["CS1705"] = ReportDiagnostic.Suppress,
                ["CS8019"] = ReportDiagnostic.Suppress
            })
                                                          .WithUsings("System");
            CSharpCompilation compilation = CSharpCompilation.Create(typeof(T).FullName, new List <SyntaxTree> {
                syntaxTree
            }, metadataReferences, compilationOptions);

            Assembly    assembly;
            EmitOptions emitOptions = new EmitOptions(debugInformationFormat: DebugInformationFormat.PortablePdb);
            using (MemoryStream assemblyStream = new MemoryStream())
            {
                using (MemoryStream pdbStream = new MemoryStream())
                {
                    var emitResult = compilation.Emit(
                        assemblyStream,
                        pdbStream,
                        options: emitOptions);

                    if (!emitResult.Success)
                    {
                        throw new Exception("Compilation error: " + string.Join("; ", emitResult.Diagnostics.Select(d => d.ToString())));
                    }

                    assemblyStream.Seek(0, SeekOrigin.Begin);
                    pdbStream.Seek(0, SeekOrigin.Begin);

                    assembly = Assembly.Load(assemblyStream.ToArray(), pdbStream.ToArray());
                }
            }

            var generatorType = assembly.GetTypes().Where(type => type.IsSubclassOf(typeof(T))).Single();
            return(generatorType);
        }