private bool ParseArguments()
        {
            ProjectPath = Options.ProjectArgument.Value;
            if (string.IsNullOrEmpty(ProjectPath))
            {
                Application.Error.WriteLine("Project path not specified.");
                return(false);
            }

            if (!OutputPathOption.HasValue())
            {
                Application.Error.WriteLine($"Option {OutputPathTemplate} does not specify a value.");
                return(false);
            }

            if (!ApplicationNameOption.HasValue())
            {
                Application.Error.WriteLine($"Option {ApplicationNameTemplate} does not specify a value.");
                return(false);
            }

            if (!Options.ContentRootOption.HasValue())
            {
                Application.Error.WriteLine($"Option {CommonOptions.ContentRootTemplate} does not specify a value.");
                return(false);
            }

            return(true);
        }
        private int Execute()
        {
            if (!ParseArguments())
            {
                return(1);
            }

            MvcServiceProvider = new MvcServiceProvider(
                ProjectPath,
                ApplicationNameOption.Value(),
                Options.ContentRootOption.Value(),
                Options.ConfigureCompilationType.Value());

            Application.Out.WriteLine("Running Razor view precompilation.");

            var stopWatch = Stopwatch.StartNew();
            var results   = GenerateCode();
            var success   = true;

            foreach (var result in results)
            {
                if (!result.GeneratorResults.Success)
                {
                    success = false;
                    foreach (var error in result.GeneratorResults.ParserErrors)
                    {
                        Application.Error.WriteLine($"{error.Location.FilePath} ({error.Location.LineIndex}): {error.Message}");
                    }
                }
            }

            if (!success)
            {
                return(1);
            }

            var precompileAssemblyName = $"{ApplicationNameOption.Value()}{ViewsFeatureProvider.PrecompiledViewsAssemblySuffix}";
            var compilation            = CompileViews(results, precompileAssemblyName);
            var resources = GetResources(results);

            var assemblyPath = Path.Combine(OutputPathOption.Value(), precompileAssemblyName + ".dll");
            var emitResult   = EmitAssembly(compilation, assemblyPath, resources);

            if (!emitResult.Success)
            {
                foreach (var diagnostic in emitResult.Diagnostics)
                {
                    Application.Error.WriteLine(CSharpDiagnosticFormatter.Instance.Format(diagnostic));
                }

                return(1);
            }

            stopWatch.Stop();
            Application.Out.WriteLine($"Precompiled views emitted to {assemblyPath}.");
            Application.Out.WriteLine($"Successfully compiled {results.Length} Razor views in {stopWatch.ElapsedMilliseconds}ms.");
            return(0);
        }
        private CSharpCompilation CompileViews(ViewCompilationInfo[] results, string assemblyname)
        {
            var compiler    = MvcServiceProvider.Compiler;
            var compilation = compiler.CreateCompilation(assemblyname);
            var syntaxTrees = new SyntaxTree[results.Length];

            string[] additionalReferences = new string[]
            {
                @"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6\Microsoft.CSharp.dll",
                //@"C:\Users\jbato\.nuget\packages\Microsoft.DiaSymReader.Native\1.4.0\runtimes\win-x64\native\Microsoft.DiaSymReader.Native.amd64.dll",
            };

            compilation = compilation.AddReferences(additionalReferences.Select(r => MetadataReference.CreateFromFile(r)));

            Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
            compilation = compilation.AddReferences(assemblies.Where(a => !a.IsDynamic).Select(a => MetadataReference.CreateFromFile(a.Location)));

            Parallel.For(0, results.Length, ParalellOptions, i =>
            {
                var result     = results[i];
                var sourceText = SourceText.From(result.GeneratorResults.GeneratedCode, Encoding.UTF8);
                var fileInfo   = result.RelativeFileInfo;
                var syntaxTree = compiler.CreateSyntaxTree(sourceText)
                                 .WithFilePath(fileInfo.FileInfo.PhysicalPath ?? fileInfo.RelativePath);
                syntaxTrees[i] = syntaxTree;
            });

            compilation = compilation.AddSyntaxTrees(syntaxTrees);
            Parallel.For(0, results.Length, ParalellOptions, i =>
            {
                results[i].TypeName = ReadTypeInfo(compilation, syntaxTrees[i]);
            });

            // Post process the compilation - run ExpressionRewritter and any user specified callbacks.
            compilation = ExpressionRewriter.Rewrite(compilation);
            var compilationContext = new RoslynCompilationContext(compilation);

            MvcServiceProvider.ViewEngineOptions.CompilationCallback(compilationContext);
            compilation = compilationContext.Compilation;

            var codeGenerator = new ViewInfoContainerCodeGenerator(compiler, compilation);

            codeGenerator.AddViewFactory(results);

            var assemblyName = new AssemblyName(ApplicationNameOption.Value());

            assemblyName = Assembly.Load(assemblyName).GetName();
            codeGenerator.AddAssemblyMetadata(assemblyName, StrongNameOptions);

            return(codeGenerator.Compilation);
        }
Esempio n. 4
0
        private void ParseArguments()
        {
            ProjectPath = Options.ProjectArgument.Value;
            if (string.IsNullOrEmpty(ProjectPath))
            {
                throw new ArgumentException("Project path not specified.");
            }

            if (!OutputPathOption.HasValue())
            {
                throw new ArgumentException($"Option {OutputPathTemplate} does not specify a value.");
            }

            if (!ApplicationNameOption.HasValue())
            {
                throw new ArgumentException($"Option {ApplicationNameTemplate} does not specify a value.");
            }
        }
        private CSharpCompilation CompileViews(ViewCompilationInfo[] results, string assemblyname)
        {
            var compiler    = MvcServiceProvider.Compiler;
            var compilation = compiler.CreateCompilation(assemblyname);
            var syntaxTrees = new SyntaxTree[results.Length];

            Parallel.For(0, results.Length, ParalellOptions, i =>
            {
                var result     = results[i];
                var sourceText = SourceText.From(result.GeneratorResults.GeneratedCode, Encoding.UTF8);
                var fileInfo   = result.RelativeFileInfo;
                var syntaxTree = compiler.CreateSyntaxTree(sourceText)
                                 .WithFilePath(fileInfo.FileInfo.PhysicalPath ?? fileInfo.RelativePath);
                syntaxTrees[i] = syntaxTree;
            });

            compilation = compilation.AddSyntaxTrees(syntaxTrees);
            Parallel.For(0, results.Length, ParalellOptions, i =>
            {
                results[i].TypeName = ReadTypeInfo(compilation, syntaxTrees[i]);
            });

            // Post process the compilation - run ExpressionRewritter and any user specified callbacks.
            compilation = ExpressionRewriter.Rewrite(compilation);
            var compilationContext = new RoslynCompilationContext(compilation);

            MvcServiceProvider.ViewEngineOptions.CompilationCallback(compilationContext);
            compilation = compilationContext.Compilation;

            var codeGenerator = new ViewInfoContainerCodeGenerator(compiler, compilation);

            codeGenerator.AddViewFactory(results);

            var assemblyName = new AssemblyName(ApplicationNameOption.Value());

            assemblyName = Assembly.Load(assemblyName).GetName();
            codeGenerator.AddAssemblyMetadata(assemblyName, StrongNameOptions);

            return(codeGenerator.Compilation);
        }