public async Task <CompilationResult> Compile(IFileInfo fileInfo)
        {
            Directory.CreateDirectory(_tempDir);
            string        outFile = Path.Combine(_tempDir, Path.GetRandomFileName() + ".dll");
            StringBuilder args    = new StringBuilder("/target:library ");

            args.AppendFormat("/out:\"{0}\" ", outFile);
            foreach (var file in  Directory.EnumerateFiles(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "*.dll"))
            {
                args.AppendFormat("/R:\"{0}\" ", file);
            }
            args.AppendFormat("\"{0}\"", fileInfo.PhysicalPath);
            var outputStream = new MemoryStream();

            // common execute
            var process  = CreateProcess(args.ToString());
            int exitCode = await Start(process, outputStream);

            string output = GetString(outputStream);

            if (exitCode != 0)
            {
                IEnumerable <CompilationMessage> messages = output.Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries)
                                                            .Skip(3)
                                                            .Select(e => new CompilationMessage(e));
                return(CompilationResult.Failed(String.Empty, messages));
            }

            var type = Assembly.LoadFrom(outFile)
                       .GetExportedTypes()
                       .First();

            return(CompilationResult.Successful(String.Empty, type));
        }
Example #2
0
        private async Task <CompilationResult> CompileCore(IFileInfo file)
        {
            var host   = new MvcRazorHost();
            var engine = new RazorTemplateEngine(host);
            GeneratorResults results;

            using (TextReader rdr = new StreamReader(file.CreateReadStream()))
            {
                results = engine.GenerateCode(rdr, '_' + Path.GetFileNameWithoutExtension(file.Name), "Asp", file.PhysicalPath ?? file.Name);
            }

            string generatedCode;

            using (var writer = new StringWriter())
                using (var codeProvider = new CSharpCodeProvider())
                {
                    codeProvider.GenerateCodeFromCompileUnit(results.GeneratedCode, writer, new CodeGeneratorOptions());
                    generatedCode = writer.ToString();
                }

            if (!results.Success)
            {
                return(CompilationResult.Failed(generatedCode, results.ParserErrors.Select(e => new CompilationMessage(e.Message))));
            }

            Directory.CreateDirectory(_tempPath);
            string tempFile = Path.Combine(_tempPath, Path.GetRandomFileName() + ".cs");

            File.WriteAllText(tempFile, generatedCode);

            _tempFileSystem.TryGetFileInfo(tempFile, out file);
            return(await _baseCompilationService.Compile(file));
        }
Example #3
0
        /// <inheritdoc />
        public CompilationResult Compile([NotNull] RelativeFileInfo file)
        {
            GeneratorResults results;

            using (var inputStream = file.FileInfo.CreateReadStream())
            {
                results = _razorHost.GenerateCode(
                    file.RelativePath, inputStream);
            }

            if (!results.Success)
            {
                var messages = results.ParserErrors.Select(e => new CompilationMessage(e.Message));
                return(CompilationResult.Failed(file.FileInfo, results.GeneratedCode, messages));
            }

            return(_compilationService.Compile(file.FileInfo, results.GeneratedCode));
        }
Example #4
0
        internal CompilationResult CompileCore(IFileInfo file)
        {
            GeneratorResults results;

            using (var inputStream = file.CreateReadStream())
            {
                Contract.Assert(file.PhysicalPath.StartsWith(_appRoot, StringComparison.OrdinalIgnoreCase));
                var rootRelativePath = file.PhysicalPath.Substring(_appRoot.Length);
                results = _razorHost.GenerateCode(rootRelativePath, inputStream);
            }

            if (!results.Success)
            {
                var messages = results.ParserErrors.Select(e => new CompilationMessage(e.Message));
                return(CompilationResult.Failed(file, results.GeneratedCode, messages));
            }

            return(_baseCompilationService.Compile(file, results.GeneratedCode));
        }
Example #5
0
        /// <inheritdoc />
        public CompilationResult Compile([NotNull] RelativeFileInfo file)
        {
            GeneratorResults results;

            using (var inputStream = file.FileInfo.CreateReadStream())
            {
                results = _razorHost.GenerateCode(
                    file.RelativePath, inputStream);
            }

            if (!results.Success)
            {
                var messages = results.ParserErrors
                               .Select(parseError => new RazorCompilationMessage(parseError, file.RelativePath));
                var failure = new RazorCompilationFailure(
                    file.RelativePath,
                    ReadFileContentsSafely(file.FileInfo),
                    messages);

                return(CompilationResult.Failed(failure));
            }

            return(_compilationService.Compile(file, results.GeneratedCode));
        }
Example #6
0
        /// <inheritdoc />
        public CompilationResult Compile([NotNull] IFileInfo fileInfo, [NotNull] string compilationContent)
        {
            // The path passed to SyntaxTreeGenerator.Generate is used by the compiler to generate symbols (pdb) that
            // map to the source file. If a file does not exist on a physical file system, PhysicalPath will be null.
            // This prevents files that exist in a non-physical file system from being debugged.
            var path = fileInfo.PhysicalPath ?? fileInfo.Name;
            var compilationSettings = _compilerOptionsProvider.GetCompilationSettings(_environment);
            var syntaxTree          = SyntaxTreeGenerator.Generate(compilationContent,
                                                                   path,
                                                                   compilationSettings);
            var references = _applicationReferences.Value;

            var assemblyName       = Path.GetRandomFileName();
            var compilationOptions = compilationSettings.CompilationOptions
                                     .WithOutputKind(OutputKind.DynamicallyLinkedLibrary);

            var compilation = CSharpCompilation.Create(assemblyName,
                                                       options: compilationOptions,
                                                       syntaxTrees: new[] { syntaxTree },
                                                       references: references);

            using (var ms = new MemoryStream())
            {
                using (var pdb = new MemoryStream())
                {
                    EmitResult result;

                    if (_supportsPdbGeneration.Value)
                    {
                        result = compilation.Emit(ms, pdbStream: pdb);
                    }
                    else
                    {
                        result = compilation.Emit(ms);
                    }

                    if (!result.Success)
                    {
                        var formatter = new DiagnosticFormatter();

                        var messages = result.Diagnostics
                                       .Where(IsError)
                                       .Select(d => GetCompilationMessage(formatter, d))
                                       .ToList();

                        return(CompilationResult.Failed(fileInfo, compilationContent, messages));
                    }

                    Assembly assembly;
                    ms.Seek(0, SeekOrigin.Begin);

                    if (_supportsPdbGeneration.Value)
                    {
                        pdb.Seek(0, SeekOrigin.Begin);
                        assembly = _loader.LoadStream(ms, pdb);
                    }
                    else
                    {
                        assembly = _loader.LoadStream(ms, assemblySymbols: null);
                    }

                    var type = assembly.GetExportedTypes()
                               .First(t => t.Name.StartsWith(_classPrefix, StringComparison.Ordinal));

                    return(UncachedCompilationResult.Successful(type, compilationContent));
                }
            }
        }