public void GetSyntaxTreeForCSharpProgramQueryReturnsCorrectSyntaxTree() { // Given Query query = GetQuery("CSharpProgram.linq"); // When SyntaxTree syntaxTree = CodeAnalysisUtil.GetSyntaxTree(query); Microsoft.CodeAnalysis.CSharp.CSharpCompilation compilation = Microsoft.CodeAnalysis.CSharp.CSharpCompilation.Create("TestCompilation", new[] { syntaxTree }); IEnumerable <Diagnostic> diagnostics = compilation.GetParseDiagnostics(); // Then Assert.IsInstanceOf <Microsoft.CodeAnalysis.CSharp.Syntax.CompilationUnitSyntax>(syntaxTree.GetRoot()); CollectionAssert.IsEmpty(diagnostics); }
private Assembly Compile(string code) { #if NETCOREAPP2_0 var coreDir = Directory.GetParent(typeof(Enumerable).GetTypeInfo().Assembly.Location); Microsoft.CodeAnalysis.CSharp.CSharpCompilation compilation = Microsoft.CodeAnalysis.CSharp.CSharpCompilation.Create("assemblyName") .WithOptions(new Microsoft.CodeAnalysis.CSharp.CSharpCompilationOptions(Microsoft.CodeAnalysis.OutputKind.DynamicallyLinkedLibrary)) .AddReferences(Microsoft.CodeAnalysis.MetadataReference.CreateFromFile(typeof(object).Assembly.Location), Microsoft.CodeAnalysis.MetadataReference.CreateFromFile(typeof(JsonConvert).Assembly.Location), Microsoft.CodeAnalysis.MetadataReference.CreateFromFile(typeof(GeneratedCodeAttribute).Assembly.Location), Microsoft.CodeAnalysis.MetadataReference.CreateFromFile(coreDir.FullName + Path.DirectorySeparatorChar + "System.Runtime.dll"), Microsoft.CodeAnalysis.MetadataReference.CreateFromFile(coreDir.FullName + Path.DirectorySeparatorChar + "System.Dynamic.Runtime.dll"), Microsoft.CodeAnalysis.MetadataReference.CreateFromFile(coreDir.FullName + Path.DirectorySeparatorChar + "System.IO.dll"), Microsoft.CodeAnalysis.MetadataReference.CreateFromFile(coreDir.FullName + Path.DirectorySeparatorChar + "System.Linq.dll"), Microsoft.CodeAnalysis.MetadataReference.CreateFromFile(coreDir.FullName + Path.DirectorySeparatorChar + "System.ObjectModel.dll"), Microsoft.CodeAnalysis.MetadataReference.CreateFromFile(coreDir.FullName + Path.DirectorySeparatorChar + "System.Linq.Expressions.dll"), Microsoft.CodeAnalysis.MetadataReference.CreateFromFile(coreDir.FullName + Path.DirectorySeparatorChar + "System.Runtime.Extensions.dll")) .AddSyntaxTrees(Microsoft.CodeAnalysis.CSharp.CSharpSyntaxTree.ParseText(code)); using (var stream = new MemoryStream()) { var result = compilation.Emit(stream); if (!result.Success) { throw new Exception(String.Join(", ", result.Diagnostics .Where(diagnostic => diagnostic.IsWarningAsError || diagnostic.Severity == Microsoft.CodeAnalysis.DiagnosticSeverity.Error) .Select(d => d.Location.GetLineSpan().StartLinePosition + " - " + d.GetMessage())) + "\n" + code); } return(Assembly.Load(stream.GetBuffer())); } #endif #if NET451 var provider = new Microsoft.CSharp.CSharpCodeProvider(); var parameters = new CompilerParameters() { GenerateInMemory = true, GenerateExecutable = false }; var compilationResult = provider.CompileAssemblyFromSource(parameters, code); Assert.False(compilationResult.Errors.HasErrors, String.Join(", ", compilationResult.Errors)); return(compilationResult.CompiledAssembly); #endif }
} // End Function EmitToArray // a utility method that creates Roslyn compilation // for the passed code. // The compilation references the collection of // passed "references" arguments plus // the mscore library (which is required for the basic // functionality). private static Microsoft.CodeAnalysis.CSharp.CSharpCompilation CreateCompilationWithMscorlib ( string assemblyOrModuleName, string code, Microsoft.CodeAnalysis.CSharp.CSharpCompilationOptions compilerOptions = null, System.Collections.Generic.IEnumerable<Microsoft.CodeAnalysis.MetadataReference> references = null) { // create the syntax tree Microsoft.CodeAnalysis.SyntaxTree syntaxTree = Microsoft.CodeAnalysis.CSharp.SyntaxFactory.ParseSyntaxTree(code, null, ""); // get the reference to mscore library Microsoft.CodeAnalysis.MetadataReference mscoreLibReference = Microsoft.CodeAnalysis.AssemblyMetadata .CreateFromFile(typeof(string).Assembly.Location) .GetReference(); // create the allReferences collection consisting of // mscore reference and all the references passed to the method System.Collections.Generic.IEnumerable< Microsoft.CodeAnalysis.MetadataReference> allReferences = new Microsoft.CodeAnalysis.MetadataReference[] {mscoreLibReference}; if (references != null) { allReferences = allReferences.Concat(references); } // create and return the compilation Microsoft.CodeAnalysis.CSharp.CSharpCompilation compilation = Microsoft.CodeAnalysis.CSharp.CSharpCompilation.Create ( assemblyOrModuleName, new[] {syntaxTree}, options: compilerOptions, references: allReferences ); return compilation; } // End Function CreateCompilationWithMscorlib
public SoftmakeAll.SDK.OperationResult <System.Text.Json.JsonElement> CompileTo(System.IO.Stream Stream) { if (Stream == null) { throw new System.Exception(System.String.Format(SoftmakeAll.SDK.NetReflector.Compiler.NullOrEmptyMessage, "Stream")); } if (System.String.IsNullOrWhiteSpace(this.OutputFileName)) { throw new System.Exception(System.String.Format(SoftmakeAll.SDK.NetReflector.Compiler.NullOrEmptyMessage, "OutputFileName")); } if ((this.CodeFiles == null) || (!(this.CodeFiles.Any()))) { throw new System.Exception(System.String.Format(SoftmakeAll.SDK.NetReflector.Compiler.NullOrEmptyMessage, "Code")); } System.Collections.Generic.List <Microsoft.CodeAnalysis.SyntaxTree> SyntaxTrees = new System.Collections.Generic.List <Microsoft.CodeAnalysis.SyntaxTree>(); foreach (System.Collections.Generic.KeyValuePair <System.String, System.String> CodeFile in this.CodeFiles.Where(c => (!(System.String.IsNullOrWhiteSpace(c.Value))))) { SyntaxTrees.Add(Microsoft.CodeAnalysis.CSharp.CSharpSyntaxTree.ParseText(Microsoft.CodeAnalysis.CSharp.CSharpSyntaxTree.ParseText(CodeFile.Value.Trim()).GetRoot().NormalizeWhitespace(new System.String(' ', this.IndentSize), System.Environment.NewLine, false).ToFullString(), null, CodeFile.Key)); } if (!(SyntaxTrees.Any())) { throw new System.Exception(System.String.Format(SoftmakeAll.SDK.NetReflector.Compiler.NullOrEmptyMessage, "Code")); } SoftmakeAll.SDK.OperationResult <System.Text.Json.JsonElement> CompileResult = new SoftmakeAll.SDK.OperationResult <System.Text.Json.JsonElement>(); System.Collections.Generic.List <Microsoft.CodeAnalysis.MetadataReference> CurrentReferences = new System.Collections.Generic.List <Microsoft.CodeAnalysis.MetadataReference>(); if (!(System.String.IsNullOrWhiteSpace(this.DefaultReferencesDirectoryPath))) { if (!(System.IO.Directory.Exists(this.DefaultReferencesDirectoryPath))) { throw new System.IO.DirectoryNotFoundException(); } else { foreach (System.String ReferencedFile in System.IO.Directory.GetFiles(this.DefaultReferencesDirectoryPath, "*.*", System.IO.SearchOption.AllDirectories)) { CurrentReferences.Add(Microsoft.CodeAnalysis.MetadataReference.CreateFromFile(ReferencedFile)); } } } if ((this.AdditionalReferences != null) && (this.AdditionalReferences.Any())) { foreach (System.String ReferencedFile in this.AdditionalReferences) { CurrentReferences.Add(Microsoft.CodeAnalysis.MetadataReference.CreateFromFile(ReferencedFile)); } } Microsoft.CodeAnalysis.CSharp.CSharpCompilationOptions CSharpCompilationOptions = new Microsoft.CodeAnalysis.CSharp.CSharpCompilationOptions ( optimizationLevel: Microsoft.CodeAnalysis.OptimizationLevel.Release, outputKind: (Microsoft.CodeAnalysis.OutputKind) this.OutputKind, platform: (Microsoft.CodeAnalysis.Platform) this.Platform ); System.IO.FileInfo OutputFileNameInfo = new System.IO.FileInfo(this.OutputFileName); System.String AssemblyName = OutputFileNameInfo.Name.Substring(0, OutputFileNameInfo.Name.Length - OutputFileNameInfo.Extension.Length); Microsoft.CodeAnalysis.CSharp.CSharpCompilation CSharpCompilation = Microsoft.CodeAnalysis.CSharp.CSharpCompilation.Create(AssemblyName, SyntaxTrees, CurrentReferences, CSharpCompilationOptions); Microsoft.CodeAnalysis.Emit.EmitResult EmitResult = CSharpCompilation.Emit(Stream); if (EmitResult.Diagnostics.Length > 0) { System.Collections.Generic.List <System.Text.Json.JsonElement> Diagnostics = new System.Collections.Generic.List <System.Text.Json.JsonElement>(); foreach (Microsoft.CodeAnalysis.Diagnostic Diagnostic in EmitResult.Diagnostics) { if ((this.OmitCompilationHiddenSeverity) && (Diagnostic.Descriptor.DefaultSeverity == Microsoft.CodeAnalysis.DiagnosticSeverity.Hidden)) { continue; } if ((this.OmitCompilationInfoSeverity) && (Diagnostic.Descriptor.DefaultSeverity == Microsoft.CodeAnalysis.DiagnosticSeverity.Info)) { continue; } if ((this.OmitCompilationWarningSeverity) && (Diagnostic.Descriptor.DefaultSeverity == Microsoft.CodeAnalysis.DiagnosticSeverity.Warning)) { continue; } System.String ID = Diagnostic.Descriptor.Id; if (ID == "CS8019") // CS8019 = using directives { continue; } System.String Severity = Diagnostic.Descriptor.DefaultSeverity.ToString(); System.String Category = Diagnostic.Descriptor.Category; System.String Message = Diagnostic.GetMessage(); System.Text.Json.JsonElement Location = new System.Text.Json.JsonElement(); if ((Diagnostic.Location != null) && (Diagnostic.Location.SourceSpan != null) && (!(Diagnostic.Location.SourceSpan.IsEmpty))) { Microsoft.CodeAnalysis.FileLinePositionSpan FileLinePositionSpan = Diagnostic.Location.GetMappedLineSpan(); System.Nullable <System.Int32> Line = null; System.Nullable <System.Int32> Character = null; if (FileLinePositionSpan.IsValid) { Line = FileLinePositionSpan.StartLinePosition.Line; Character = FileLinePositionSpan.StartLinePosition.Character; } Location = new { Diagnostic.Location.SourceTree.FilePath, Line, Character, Code = Diagnostic.Location.SourceTree.ToString().Substring(Diagnostic.Location.SourceSpan.Start, Diagnostic.Location.SourceSpan.End - Diagnostic.Location.SourceSpan.Start) }.ToJsonElement(); } Diagnostics.Add(new { Severity, Category, ID, Message, Location }.ToJsonElement()); } CompileResult.Data = Diagnostics.ToJsonElement(); } CompileResult.ExitCode = System.Convert.ToInt16((!(EmitResult.Success)) ? -1 : CompileResult.Data.IsValid() ? 1 : 0); return(CompileResult); }
public static void Test() { try { // code for class A string classAString = @"public class A { public static string Print() { return ""Hello ""; } }"; // code for class B (to spice it up, it is a // subclass of A even though it is almost not needed // for the demonstration) string classBString = @"public class B : A { public static string Print() { return ""World!""; } }"; // the main class Program contain static void Main() // that calls A.Print() and B.Print() methods string mainProgramString = @"public class Program { public static void Main() { System.Console.WriteLine(""Ni hao !""); // System.Console.Write(A.Print()); // System.Console.WriteLine(B.Print()); } }"; #region class A compilation into A.netmodule // create Roslyn compilation for class A Microsoft.CodeAnalysis.CSharp.CSharpCompilation compilationA = CreateCompilationWithMscorlib ( "A", classAString, compilerOptions: new Microsoft.CodeAnalysis.CSharp.CSharpCompilationOptions( Microsoft.CodeAnalysis.OutputKind.NetModule) ); // emit the compilation result to a byte array // corresponding to A.netmodule byte code byte[] compilationAResult = compilationA.EmitToArray(); // create a reference to A.netmodule Microsoft.CodeAnalysis.MetadataReference referenceA = Microsoft.CodeAnalysis.ModuleMetadata .CreateFromImage(compilationAResult) .GetReference(display: "A.netmodule"); #endregion class A compilation into A.netmodule #region class B compilation into B.netmodule // create Roslyn compilation for class A Microsoft.CodeAnalysis.CSharp.CSharpCompilation compilationB = CreateCompilationWithMscorlib ( "B", classBString, compilerOptions: new Microsoft.CodeAnalysis.CSharp.CSharpCompilationOptions( Microsoft.CodeAnalysis.OutputKind.NetModule), // since class B extends A, we need to // add a reference to A.netmodule references: new[] {referenceA} ); // emit the compilation result to a byte array // corresponding to B.netmodule byte code byte[] compilationBResult = compilationB.EmitToArray(); // create a reference to B.netmodule Microsoft.CodeAnalysis.MetadataReference referenceB = Microsoft.CodeAnalysis.ModuleMetadata .CreateFromImage(compilationBResult) .GetReference(display: "B.netmodule"); #endregion class B compilation into B.netmodule #region main program compilation into the assembly // var met = Microsoft.CodeAnalysis.AssemblyMetadata.CreateFromFile(typeof(System.Console).Assembly.Location); Microsoft.CodeAnalysis.MetadataReference sysCorlib = Microsoft.CodeAnalysis.MetadataReference.CreateFromFile(typeof(object).Assembly.Location); Microsoft.CodeAnalysis.MetadataReference sysConsole = Microsoft.CodeAnalysis.MetadataReference.CreateFromFile(typeof(System.Console).Assembly.Location); Microsoft.CodeAnalysis.MetadataReference sysRuntime = Microsoft.CodeAnalysis.MetadataReference.CreateFromFile(typeof(System.Runtime.AssemblyTargetedPatchBandAttribute).Assembly.Location); // Microsoft.CodeAnalysis.MetadataReference sysRuntimeLoader = Microsoft.CodeAnalysis.MetadataReference.CreateFromFile(typeof(System.Runtime.Loader.AssemblyLoadContext).Assembly.Location); // Microsoft.CodeAnalysis.MetadataReference sysAssembly = Microsoft.CodeAnalysis.MetadataReference.CreateFromFile(typeof(System.Reflection.Assembly).Assembly.Location); // create the Roslyn compilation for the main program with // ConsoleApplication compilation options // adding references to A.netmodule and B.netmodule Microsoft.CodeAnalysis.CSharp.CSharpCompilation mainCompilation = CreateCompilationWithMscorlib ( "program", mainProgramString, // note that here we pass the OutputKind set to ConsoleApplication compilerOptions: new Microsoft.CodeAnalysis.CSharp.CSharpCompilationOptions( Microsoft.CodeAnalysis.OutputKind.ConsoleApplication ), references: new[] { sysRuntime, sysCorlib, sysConsole, referenceA, referenceB } ); //.WithOptions(new CSharpCompilationOptions(Microsoft.CodeAnalysis.OutputKind.DynamicallyLinkedLibrary)) // Emit the byte result of the compilation byte[] result = mainCompilation.EmitToArray(); // Load the resulting assembly into the domain. System.Reflection.Assembly assembly = System.Reflection.Assembly.Load(result); // System.Type t = assembly.GetType("Program"); // System.Reflection.MethodInfo mainMethod = t.GetMethod("Main"); // mainMethod.Invoke(null, null); #endregion main program compilation into the assembly // .NET Core doesn't support modules... (by design) // load the A.netmodule and B.netmodule into the assembly. // assembly.LoadModule("A.netmodule", compilationAResult); // assembly.LoadModule("B.netmodule", compilationBResult); #region Test the program // here we get the Program type and // call its static method Main() // to test the program. // It should write "Hello world!" // to the console // get the type Program from the assembly System.Type programType = assembly.GetType("Program"); // Get the static Main() method info from the type System.Reflection.MethodInfo method = programType.GetMethod("Main"); // invoke Program.Main() static method method.Invoke(null, null); #endregion Test the program } catch (System.Exception ex) { System.Console.WriteLine(ex.ToString()); } } // End Sub Test