Beispiel #1
0
        private CompilationResult CompileCSharp(string fullClassName, IFileInfo file, bool success, List <CompilationMessage> messages, CodeCompileUnit codeCompileUnit)
        {
            // Generate code text
            var code = new StringBuilder();

            using (var provider = new CSharpCodeProvider())
            {
                using (var writer = new StringWriter(code))
                {
                    provider.GenerateCodeFromCompileUnit(codeCompileUnit, writer, new CodeGeneratorOptions());
                }
            }

            // Parse
            SyntaxTree tree = SyntaxTree.ParseText/*.ParseCompilationUnit*/ (code.ToString(), "__Generated.cs");

            // Create a compilation
            CSCompilation comp = CSCompilation.Create(
                "Compiled",
                new CompilationOptions(OutputKind.DynamicallyLinkedLibrary),
                syntaxTrees: new[] { tree },
                references: new[]
            {
                new MetadataFileReference(typeof(object).Assembly.Location),
                new MetadataFileReference(typeof(Enumerable).Assembly.Location),
                new MetadataFileReference(typeof(PageBase).Assembly.Location)
            });

            // Emit to a collectable assembly
            AssemblyBuilder asm = AssemblyBuilder.DefineDynamicAssembly(
                new AssemblyName("Razor_" + Guid.NewGuid().ToString("N")), AssemblyBuilderAccess.RunAndCollect);
            ModuleBuilder        mod    = asm.DefineDynamicModule("RazorCompilation");
            ReflectionEmitResult result = comp.Emit(mod);

            // Extract the type
            Type typ = null;

            if (result.Success)
            {
                typ = asm.GetType(fullClassName);
            }
            else
            {
                foreach (var diagnostic in result.Diagnostics)
                {
                    FileLinePositionSpan span         = diagnostic.Location.GetLineSpan(true);
                    LinePosition         linePosition = span.StartLinePosition;
                    messages.Add(new CompilationMessage(
                                     SeverityMap[diagnostic.Info.Severity],
                                     diagnostic.Info.GetMessage(),
                                     new FileLocation(
                                         span.Path,
                                         linePosition.Line,
                                         linePosition.Character,
                                         String.Equals(span.Path, "__Generated.cs", StringComparison.OrdinalIgnoreCase))));
                }
            }

            // Create a compilation result
            if (success && result.Success)
            {
                return(CompilationResult.Successful(code.ToString(), typ, messages));
            }
            return(CompilationResult.Failed(code.ToString(), messages));
        }