private AssemblyMetadata CompileWithRoslynInMemory(string[] source) { Console.WriteLine($"RoslynCompile> Compiling sources with Roslyn: {string.Join(" ", source)}\n"); var srcFileName = Path.GetFileNameWithoutExtension(this.FirstSource); var assemblyName = srcFileName; var defineSeparators = new[] { ';', ' ' }; var syntaxTrees = source.Select( s => CSharpSyntaxTree.ParseText( SourceText.From(new FileStream(s, FileMode.Open, FileAccess.Read), Encoding.UTF8), new CSharpParseOptions( LanguageVersion.Experimental, preprocessorSymbols: this.Options["DefineConstants"].Split(defineSeparators, StringSplitOptions.RemoveEmptyEntries)), s)); var assemblies = new List <MetadataImageReference>(); this.Assemblies = this.LoadReferencesForCompiling(assemblies); Console.WriteLine($" > References: {string.Join(" ", assemblies.Select(asm => asm.Display))}"); var options = new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary).WithAllowUnsafe(true) .WithOptimizations(!DebugOutput) .WithRuntimeMetadataVersion("4.5"); var compilation = CSharpCompilation.Create(assemblyName, syntaxTrees, assemblies.ToArray(), options); var dllStream = new MemoryStream(); var pdbStream = new MemoryStream(); PEModuleBuilder.OnMethodBoundBodySynthesizedDelegate peModuleBuilderOnOnMethodBoundBodySynthesized = (symbol, body) => { var key = symbol.ToKeyString(); Debug.Assert(!this.boundBodyByMethodSymbol.ContainsKey(key), "Check if method is partial"); this.boundBodyByMethodSymbol[key] = body; }; PEModuleBuilder.OnSourceMethodDelegate peModuleBuilderOnSourceMethod = (symbol, sourceMethod) => { var key = symbol.ToKeyString(); Debug.Assert(!this.sourceMethodByMethodSymbol.ContainsKey(key), "Check if method is partial"); this.sourceMethodByMethodSymbol[key] = sourceMethod; }; PEModuleBuilder.OnMethodBoundBodySynthesized += peModuleBuilderOnOnMethodBoundBodySynthesized; PEModuleBuilder.OnSourceMethod += peModuleBuilderOnSourceMethod; var result = compilation.Emit(peStream: dllStream, pdbStream: pdbStream); PEModuleBuilder.OnMethodBoundBodySynthesized -= peModuleBuilderOnOnMethodBoundBodySynthesized; PEModuleBuilder.OnSourceMethod -= peModuleBuilderOnSourceMethod; if (result.Diagnostics.Length > 0) { var errors = result.Diagnostics.Where(d => d.Severity == DiagnosticSeverity.Error).ToList(); Console.WriteLine(@"Errors: {0}", errors.Count); foreach (var diagnostic in errors) { Console.WriteLine(diagnostic); } var diagnostics = result.Diagnostics.Where(d => d.Severity != DiagnosticSeverity.Error); Console.WriteLine(@"Warnings/Info: {0}", diagnostics.Count()); foreach (var diagnostic in diagnostics) { Console.WriteLine(diagnostic); } } dllStream.Flush(); dllStream.Position = 0; pdbStream.Flush(); pdbStream.Position = 0; // Successful Compile return(AssemblyMetadata.CreateFromImageStream(dllStream)); }
private bool CompileTo(string[] source, Stream dllStream, Stream pdbStream) { var assemblyName = Path.GetFileNameWithoutExtension(this.FirstSource); var defineSeparators = new[] { ';', ',', ' ' }; var syntaxTrees = source.Select( s => CSharpSyntaxTree.ParseText( SourceText.From(new FileStream(s, FileMode.Open, FileAccess.Read), Encoding.UTF8), new CSharpParseOptions( LanguageVersion.Latest, preprocessorSymbols: (this.Options["DefineConstants"] ?? string.Empty).Split(defineSeparators, StringSplitOptions.RemoveEmptyEntries)), s)); var assemblies = new List <MetadataImageReference>(); this.Assemblies = this.LoadReferencesForCompiling(assemblies); var options = new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary).WithAllowUnsafe(true) .WithOptimizationLevel(DebugOutput ? OptimizationLevel.Debug : OptimizationLevel.Release) .WithConcurrentBuild(true); var compilation = CSharpCompilation.Create(assemblyName, syntaxTrees, assemblies.ToArray(), options); PEModuleBuilder.OnMethodBoundBodySynthesizedDelegate peModuleBuilderOnOnMethodBoundBodySynthesized = (symbol, body) => { var key = symbol.ToKeyString(); Debug.Assert(!this.boundBodyByMethodSymbol.ContainsKey(key), "Check if method is partial"); this.boundBodyByMethodSymbol[key] = body; }; PEModuleBuilder.OnSourceMethodDelegate peModuleBuilderOnSourceMethod = (symbol, sourceMethod) => { var key = symbol.ToKeyString(); Debug.Assert(!this.sourceMethodByMethodSymbol.ContainsKey(key), "Check if method is partial"); this.sourceMethodByMethodSymbol[key] = sourceMethod; }; PEModuleBuilder.OnMethodBoundBodySynthesized += peModuleBuilderOnOnMethodBoundBodySynthesized; PEModuleBuilder.OnSourceMethod += peModuleBuilderOnSourceMethod; var result = compilation.Emit(peStream: dllStream, pdbStream: pdbStream); PEModuleBuilder.OnMethodBoundBodySynthesized -= peModuleBuilderOnOnMethodBoundBodySynthesized; PEModuleBuilder.OnSourceMethod -= peModuleBuilderOnSourceMethod; if (result.Diagnostics.Length > 0) { var errors = result.Diagnostics.Where(d => d.Severity == DiagnosticSeverity.Error).ToList(); Console.WriteLine(@"Errors: {0}", errors.Count); foreach (var diagnostic in errors) { Console.WriteLine(diagnostic); } var diagnostics = result.Diagnostics.Where(d => d.Severity != DiagnosticSeverity.Error); Console.WriteLine(@"Warnings/Info: {0}", diagnostics.Count()); foreach (var diagnostic in diagnostics) { Console.WriteLine(diagnostic); } return(errors.Count == 0); } return(true); }