66using System . Collections . Generic ;
77using System . IO ;
88using System . Linq ;
9+ using System . Reflection ;
10+ using System . Text ;
911
1012namespace avaness . PluginLoader . Compiler
1113{
1214 public class RoslynCompiler
1315 {
1416 private readonly List < Source > source = new List < Source > ( ) ;
17+ private bool debugBuild ;
18+
19+ public RoslynCompiler ( bool debugBuild = false )
20+ {
21+ this . debugBuild = debugBuild ;
22+ }
1523
1624 public void Load ( Stream s , string name )
1725 {
1826 MemoryStream mem = new MemoryStream ( ) ;
1927 using ( mem )
2028 {
2129 s . CopyTo ( mem ) ;
22- source . Add ( new Source ( mem , name ) ) ;
30+ source . Add ( new Source ( mem , name , debugBuild ) ) ;
2331 }
2432 }
2533
26- public byte [ ] Compile ( string assemblyName )
34+ public byte [ ] Compile ( string assemblyName , out byte [ ] symbols )
2735 {
36+ symbols = null ;
37+
2838 CSharpCompilation compilation = CSharpCompilation . Create (
29- assemblyName ,
30- syntaxTrees : source . Select ( x => x . Tree ) ,
31- references : RoslynReferences . EnumerateAllReferences ( ) ,
32- options : new CSharpCompilationOptions ( OutputKind . DynamicallyLinkedLibrary , optimizationLevel : OptimizationLevel . Release ) ) ;
39+ assemblyName ,
40+ syntaxTrees : source . Select ( x => x . Tree ) ,
41+ references : RoslynReferences . EnumerateAllReferences ( ) ,
42+ options : new CSharpCompilationOptions (
43+ OutputKind . DynamicallyLinkedLibrary ,
44+ optimizationLevel : debugBuild ? OptimizationLevel . Debug : OptimizationLevel . Release ) ) ;
3345
34- using ( var ms = new MemoryStream ( ) )
46+ using ( MemoryStream pdb = new MemoryStream ( ) )
47+ using ( MemoryStream ms = new MemoryStream ( ) )
3548 {
3649 // write IL code into memory
37- EmitResult result = compilation . Emit ( ms ) ;
50+ EmitResult result ;
51+ if ( debugBuild )
52+ {
53+ result = compilation . Emit ( ms , pdb ,
54+ embeddedTexts : source . Select ( x => x . Text ) ,
55+ options : new EmitOptions ( debugInformationFormat : DebugInformationFormat . PortablePdb , pdbFilePath : Path . ChangeExtension ( assemblyName , "pdb" ) ) ) ;
56+ }
57+ else
58+ {
59+ result = compilation . Emit ( ms ) ;
60+ }
61+
3862 if ( ! result . Success )
3963 {
4064 // handle exceptions
@@ -52,24 +76,38 @@ public byte[] Compile(string assemblyName)
5276 }
5377 else
5478 {
55- // load this 'virtual' DLL so that we can use
79+ if ( debugBuild )
80+ {
81+ pdb . Seek ( 0 , SeekOrigin . Begin ) ;
82+ symbols = pdb . ToArray ( ) ;
83+ }
84+
5685 ms . Seek ( 0 , SeekOrigin . Begin ) ;
5786 return ms . ToArray ( ) ;
5887 }
5988 }
6089
6190 }
6291
63-
6492 private class Source
6593 {
6694 public string Name { get ; }
6795 public SyntaxTree Tree { get ; }
96+ public EmbeddedText Text { get ; }
6897
69- public Source ( Stream s , string name )
98+ public Source ( Stream s , string name , bool includeText )
7099 {
71100 Name = name ;
72- Tree = CSharpSyntaxTree . ParseText ( SourceText . From ( s ) , new CSharpParseOptions ( LanguageVersion . Latest ) ) ;
101+ SourceText source = SourceText . From ( s , canBeEmbedded : includeText ) ;
102+ if ( includeText )
103+ {
104+ Text = EmbeddedText . FromSource ( name , source ) ;
105+ Tree = CSharpSyntaxTree . ParseText ( source , new CSharpParseOptions ( LanguageVersion . Latest ) , name ) ;
106+ }
107+ else
108+ {
109+ Tree = CSharpSyntaxTree . ParseText ( source , new CSharpParseOptions ( LanguageVersion . Latest ) ) ;
110+ }
73111 }
74112 }
75113 }
0 commit comments