private static void CodeGenerateRazorComponents(GeneratorExecutionContext context, RazorSourceGenerationContext razorContext, RazorProjectEngine projectEngine) { var files = razorContext.RazorFiles; var arraypool = ArrayPool <(string, SourceText)> .Shared; var outputs = arraypool.Rent(files.Count); Parallel.For(0, files.Count, GetParallelOptions(context), i => { var file = files[i]; var projectItem = projectEngine.FileSystem.GetItem(file.NormalizedPath, FileKinds.Component); var codeDocument = projectEngine.Process(projectItem); var csharpDocument = codeDocument.GetCSharpDocument(); for (var j = 0; j < csharpDocument.Diagnostics.Count; j++) { var razorDiagnostic = csharpDocument.Diagnostics[j]; var csharpDiagnostic = razorDiagnostic.AsDiagnostic(); context.ReportDiagnostic(csharpDiagnostic); } var hint = GetIdentifierFromPath(file.NormalizedPath); var generatedCode = csharpDocument.GeneratedCode; if (razorContext.WriteGeneratedContent) { var path = file.GeneratedOutputPath; Directory.CreateDirectory(Path.GetDirectoryName(path)); File.WriteAllText(path, generatedCode); } outputs[i] = (hint, SourceText.From(generatedCode, Encoding.UTF8)); });
private CompilationResult GetCompilation(RazorProjectItem projectItem, RazorProjectFileSystem projectFileSystem) { using (IServiceScope scope = _serviceScopeFactory.CreateScope()) { IServiceProvider serviceProvider = scope.ServiceProvider; // See RazorViewCompiler.CompileAndEmit() RazorProjectEngine projectEngine = serviceProvider.GetRequiredService <RazorProjectEngine>(); RazorCodeDocument codeDocument = projectEngine.Process(projectItem); RazorCSharpDocument cSharpDocument = codeDocument.GetCSharpDocument(); if (cSharpDocument.Diagnostics.Count > 0) { throw (Exception)CreateCompilationFailedException.Invoke( null, new object[] { codeDocument, cSharpDocument.Diagnostics }); } // Use the RazorViewCompiler to finish compiling the view for consistency with layouts IViewCompilerProvider viewCompilerProvider = serviceProvider.GetRequiredService <IViewCompilerProvider>(); IViewCompiler viewCompiler = viewCompilerProvider.GetCompiler(); Assembly assembly = (Assembly)CompileAndEmitMethod.Invoke( viewCompiler, new object[] { codeDocument, cSharpDocument.GeneratedCode }); // Get the runtime item RazorCompiledItemLoader compiledItemLoader = new RazorCompiledItemLoader(); RazorCompiledItem compiledItem = compiledItemLoader.LoadItems(assembly).SingleOrDefault(); return(new CompilationResult(compiledItem)); } }
private static SyntaxTree GenerateSyntaxTree(RazorProjectItem razorProjectItem, RazorProjectEngine razorProjectEngine) { RazorCodeDocument razorCodeDocument = razorProjectEngine.Process(razorProjectItem); RazorCSharpDocument razorCSharpDocument = razorCodeDocument.GetCSharpDocument(); return(CSharpSyntaxTree.ParseText(razorCSharpDocument.GeneratedCode)); }
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 => MetadataReference.CreateFromFile(ass.Location)) .Concat(options.MetadataReferences) .ToList(), 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()}") { Errors = errors, GeneratedCode = razorCSharpDocument.GeneratedCode }; throw exception; } memoryStream.Position = 0; return(memoryStream); }
public TemplateFactoryResult Create(string content) { var result = _engine.Process(new TemplateRazorProjectItem(content)); return(result.GetCSharpDocument().Diagnostics.Any() ? GenerateError(result) : Compile(result)); }
static RazorPageGeneratorResult GenerateCodeFile(RazorProjectEngine projectEngine, RazorProjectItem projectItem) { var codeDocument = projectEngine.Process(projectItem); var cSharpDocument = codeDocument.GetCSharpDocument(); return(new RazorPageGeneratorResult { FilePath = projectItem.PhysicalPath, GeneratedCode = cSharpDocument.GeneratedCode, }); }
protected override string GetCode(string content, CancellationToken cancellationToken) { var sourceDocument = RazorSourceDocument.Create(content, "_"); var codeDocument = _projectEngine.Process(sourceDocument, fileKind: null, importSources: null, tagHelpers: null); var parsedDocument = codeDocument.GetCSharpDocument(); if (parsedDocument.Diagnostics.OfType <RazorDiagnostic>().Any(d => d.Severity == RazorDiagnosticSeverity.Error)) { throw new ArgumentException("Razor code has errors.", nameof(content)); } return(parsedDocument.GeneratedCode); }
public string Generate(string filePath) { var razorItem = _projectEngine.FileSystem.GetItem(filePath); var codeDocument = _projectEngine.Process(razorItem); var csharpDocument = codeDocument.GetCSharpDocument(); if (csharpDocument.Diagnostics.Any()) { var diagnostics = string.Join(Environment.NewLine, csharpDocument.Diagnostics); throw new InvalidOperationException($"One or more parse errors encountered. This will not prevent the generator from continuing: {Environment.NewLine}{diagnostics}."); } return(csharpDocument.GeneratedCode); }
private OutputItem[] GenerateCode(RazorProjectEngine engine, SourceItem[] inputs) { var outputs = new OutputItem[inputs.Length]; Parallel.For(0, outputs.Length, new ParallelOptions() { MaxDegreeOfParallelism = Debugger.IsAttached ? 1 : 4 }, i => { var inputItem = inputs[i]; var codeDocument = engine.Process(engine.FileSystem.GetItem(inputItem.FilePath)); var csharpDocument = codeDocument.GetCSharpDocument(); outputs[i] = new OutputItem(inputItem, csharpDocument); }); return(outputs); }
private static RazorPageGeneratorResult GenerateCodeFile(RazorProjectEngine projectEngine, RazorProjectItem projectItem) { var projectItemWrapper = new FileSystemRazorProjectItemWrapper(projectItem); var codeDocument = projectEngine.Process(projectItemWrapper); var cSharpDocument = codeDocument.GetCSharpDocument(); if (cSharpDocument.Diagnostics.Any()) { var diagnostics = string.Join(Environment.NewLine, cSharpDocument.Diagnostics); Console.WriteLine($"One or more parse errors encountered. This will not prevent the generator from continuing: {Environment.NewLine}{diagnostics}."); } var generatedCodeFilePath = Path.ChangeExtension(projectItem.PhysicalPath, ".Designer.cs"); return(new RazorPageGeneratorResult { FilePath = generatedCodeFilePath, GeneratedCode = cSharpDocument.GeneratedCode, }); }
private void GenerateViews(GeneratorExecutionContext context, RazorSourceGenerationContext razorContext, RazorProjectEngine projectEngine) { var files = razorContext.CshtmlFiles; Parallel.For(0, files.Count, GetParallelOptions(context), i => { var file = files[i]; var codeDocument = projectEngine.Process(projectEngine.FileSystem.GetItem(file.NormalizedPath, FileKinds.Legacy)); var csharpDocument = codeDocument.GetCSharpDocument(); for (var j = 0; j < csharpDocument.Diagnostics.Count; j++) { var razorDiagnostic = csharpDocument.Diagnostics[j]; var csharpDiagnostic = razorDiagnostic.AsDiagnostic(); context.ReportDiagnostic(csharpDiagnostic); } Directory.CreateDirectory(Path.GetDirectoryName(file.GeneratedOutputPath)); File.WriteAllText(file.GeneratedOutputPath, csharpDocument.GeneratedCode); }); }
public void Generate(string inputFileName, string outputFileName) { // normalize file names inputFileName = Path.GetFullPath(inputFileName); outputFileName = Path.GetFullPath(outputFileName); using (var stream = new FileStream(inputFileName, FileMode.Open, FileAccess.Read, FileShare.Read)) using (var reader = new StreamReader(stream)) { var relativeInputFileName = $"{Path.DirectorySeparatorChar}{PathTools.GetRelativePath($"{ProjectDirectory}{Path.DirectorySeparatorChar}", inputFileName)}"; var item = engine.FileSystem.GetItem(relativeInputFileName, "mvc"); var codeDocument = engine.Process(item); var result = codeDocument.GetCSharpDocument(); // normalize new lines (is there better way to do this?) var code = result.GeneratedCode.Replace("\r\n", "\n"); if (File.Exists(outputFileName)) { using (var md5 = MD5.Create()) /*DevSkim: ignore DS126858*/ using (var inputStream = File.OpenRead(outputFileName)) { var codeHash = md5.ComputeHash(inputStream); var fileHash = md5.ComputeHash(Encoding.GetBytes(code)); if (codeHash.SequenceEqual(fileHash)) { return; } } } using (var outputStream = new FileStream(outputFileName, FileMode.Create, FileAccess.Write, FileShare.Read)) using (var writer = new StreamWriter(outputStream, Encoding)) { writer.Write(code); } } }
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); }
/// <summary> /// Getting the generated code through Microsoft.AspNetCore.Razor.Language /// </summary> /// <param name="dynamicTemplateNamespace"></param> /// <param name="templateSourceCode"></param> /// <param name="generatedCSharpClassName"></param> /// <param name="classBaseType"></param> /// <param name="templateFile"></param> /// <returns></returns> public static string GetGeneratedCode(string dynamicTemplateNamespace, string templateSourceCode, string generatedCSharpClassName, string classBaseType, string templateFile = null) { string systemPath = Directory.GetCurrentDirectory(); string path = null; if (string.IsNullOrWhiteSpace(templateFile)) { path = systemPath; } else { path = Path.GetDirectoryName(templateFile); } RazorProjectFileSystem fs = RazorProjectFileSystem.Create(path); // or '.' RazorProjectEngine engine = RazorProjectEngine.Create(RazorConfiguration.Default, fs, (builder) => { InheritsDirective.Register(builder); FunctionsDirective.Register(builder); SectionDirective.Register(builder); builder.ConfigureClass((document, @class) => { @class.ClassName = generatedCSharpClassName; }); builder.SetNamespace(dynamicTemplateNamespace); // define a namespace for the Template class builder.SetBaseType(classBaseType); builder.AddDefaultImports("@using System", "@using System.Threading.Tasks", "@using System.Collections.Generic", "@using System.Linq", "@using System.Text", "@using RazorEngine", "@using RazorEngine.Templating"); }); string razorRelativePath; string randomRazorFileFullPath = null; if (string.IsNullOrEmpty(templateFile)) { razorRelativePath = Path.GetRandomFileName(); randomRazorFileFullPath = Path.Combine(systemPath, razorRelativePath); File.AppendAllText(randomRazorFileFullPath, templateSourceCode ?? string.Empty, System.Text.Encoding.UTF8); } else { razorRelativePath = templateFile; } RazorProjectItem item = fs.GetItem(razorRelativePath); RazorCodeDocument codeDocument = engine.Process(item); RazorCSharpDocument csharpDocument = codeDocument.GetCSharpDocument(); if (!string.IsNullOrEmpty(randomRazorFileFullPath)) { try { File.Delete(randomRazorFileFullPath); } catch (Exception) { } } if (csharpDocument.Diagnostics.Any()) { var diagnostics = string.Join(Environment.NewLine, csharpDocument.Diagnostics); throw new InvalidOperationException($"One or more parse errors encountered. This will not prevent the generator from continuing: {Environment.NewLine}{diagnostics}."); } //Manual loading of assemblies to prevent DLLs from being lost when compiling classes AppDomain.CurrentDomain.Load(typeof(RazorCompiledItemAttribute).Assembly.FullName); //手动加载程序集,防止编译的类时找不到 DLL return(csharpDocument.GeneratedCode); }
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); }