Example #1
0
        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));
            });
Example #2
0
        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));
        }
Example #4
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 => 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));
        }
Example #6
0
        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);
        }
Example #9
0
        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);
        }
Example #10
0
        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,
            });
        }
Example #11
0
        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);
            });
        }
Example #12
0
        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);
                        }
                }
        }
Example #13
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);
        }
        /// <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);
        }
Example #15
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);
        }