示例#1
0
 private static void TraceCompilaitionDiagnostics(EmitResult emitResult)
 {
     Trace.WriteLine("ERROR: Compilation Failed!");
     foreach (var diag in emitResult.Diagnostics)
     {
         var message = string.Format("[{0}] {1}", diag.Location.GetLineSpan(false),
                                     diag.Info.GetMessage());
         Trace.WriteLine(message);
     }
 }
 public SuccessfulCompileResult(AssemblyLoadContext assemblyLoadContext, EmitResult compilationResult)
 {
     AssemblyLoadContext = assemblyLoadContext;
     CompilationResult   = compilationResult;
 }
        public IDiagnosticResult EmitAssembly(string outputPath)
        {
            IList <ResourceDescription> resources = CompilationContext.Resources;

            var assemblyPath = Path.Combine(outputPath, Name + ".dll");
            var pdbPath      = Path.Combine(outputPath, Name + ".pdb");
            var xmlDocPath   = Path.Combine(outputPath, Name + ".xml");

            // REVIEW: Memory bloat?
            using (var xmlDocStream = new MemoryStream())
                using (var pdbStream = new MemoryStream())
                    using (var assemblyStream = new MemoryStream())
                    {
                        Trace.TraceInformation("[{0}]: Emitting assembly for {1}", GetType().Name, Name);

                        var sw = Stopwatch.StartNew();

                        EmitResult result = null;

                        if (_supportsPdbGeneration.Value)
                        {
                            var options = new EmitOptions(pdbFilePath: pdbPath);
                            result = CompilationContext.Compilation.Emit(assemblyStream, pdbStream: pdbStream, xmlDocumentationStream: xmlDocStream, manifestResources: resources, options: options);
                        }
                        else
                        {
                            result = CompilationContext.Compilation.Emit(assemblyStream, xmlDocumentationStream: xmlDocStream, manifestResources: resources);
                        }

                        sw.Stop();

                        Trace.TraceInformation("[{0}]: Emitted {1} in {2}ms", GetType().Name, Name, sw.ElapsedMilliseconds);

                        var diagnostics = new List <Diagnostic>(CompilationContext.Diagnostics);
                        diagnostics.AddRange(result.Diagnostics);

                        if (!result.Success ||
                            diagnostics.Any(RoslynDiagnosticUtilities.IsError))
                        {
                            return(CreateDiagnosticResult(result.Success, diagnostics));
                        }

                        // Ensure there's an output directory
                        Directory.CreateDirectory(outputPath);

                        assemblyStream.Position = 0;
                        pdbStream.Position      = 0;
                        xmlDocStream.Position   = 0;

                        using (var assemblyFileStream = File.Create(assemblyPath))
                        {
                            assemblyStream.CopyTo(assemblyFileStream);
                        }

                        using (var xmlDocFileStream = File.Create(xmlDocPath))
                        {
                            xmlDocStream.CopyTo(xmlDocFileStream);
                        }

                        if (!PlatformHelper.IsMono)
                        {
                            using (var pdbFileStream = File.Create(pdbPath))
                            {
                                pdbStream.CopyTo(pdbFileStream);
                            }
                        }

                        return(CreateDiagnosticResult(result.Success, diagnostics));
                    }
        }
示例#4
0
        public async Task <bool> RunAsync()
        {
            try
            {
                // this parameter was introduced in rc3, all call to it seem to be using RuntimeEnvironment.GetRuntimeDirectory()
                // https://github.com/dotnet/roslyn/blob/0382e3e3fc543fc483090bff3ab1eaae39dfb4d9/src/Compilers/CSharp/csc/Program.cs#L18
                var sdkDirectory = RuntimeEnvironment.GetRuntimeDirectory();

                CscArgs     = CSharpCommandLineParser.Default.Parse(_precompilationCommandLineArgs.Arguments, _precompilationCommandLineArgs.BaseDirectory, sdkDirectory);
                Diagnostics = new List <Diagnostic>(CscArgs.Errors);

                // load those before anything else hooks into our AssemlbyResolve...
                var compilationModules = LoadModules().ToList();

                if (Diagnostics.Any())
                {
                    return(false);
                }
                Encoding = CscArgs.Encoding ?? new UTF8Encoding(false); // utf8 without bom

                var pdbPath    = CscArgs.PdbPath;
                var outputPath = Path.Combine(CscArgs.OutputDirectory, CscArgs.OutputFileName);

                if (!CscArgs.EmitPdb)
                {
                    pdbPath = null;
                }
                else if (string.IsNullOrWhiteSpace(pdbPath))
                {
                    pdbPath = Path.ChangeExtension(outputPath, ".pdb");
                }

                using (var workspace = CreateWokspace())
                    using (var analysisCts = new CancellationTokenSource())
                        using (var peStream = new MemoryStream())
                            using (var pdbStream = !string.IsNullOrWhiteSpace(pdbPath) ? new MemoryStream() : null)
                                using (var xmlDocumentationStream = !string.IsNullOrWhiteSpace(CscArgs.DocumentationPath) ? new MemoryStream() : null)
                                {
                                    EmitResult               emitResult  = null;
                                    var                      project     = CreateProject(workspace);
                                    CSharpCompilation        compilation = null;
                                    CompilationWithAnalyzers compilationWithAnalyzers = null;
                                    try
                                    {
                                        compilation = await project.GetCompilationAsync() as CSharpCompilation;
                                    }
                                    catch (Exception ex)
                                    {
                                        Console.WriteLine("error: failed to create compilation: " + ex.Message);
                                        return(false);
                                    }

                                    var context = new CompileContext(compilationModules);
                                    context.Before(new BeforeCompileContext
                                    {
                                        Arguments   = CscArgs,
                                        Compilation = compilation.AddSyntaxTrees(GeneratedSyntaxTrees()),
                                        Diagnostics = Diagnostics,
                                    });

                                    CscArgs     = context.BeforeCompileContext.Arguments;
                                    compilation = context.BeforeCompileContext.Compilation;

                                    var analyzers = project.AnalyzerReferences.SelectMany(x => x.GetAnalyzers(project.Language)).ToImmutableArray();
                                    if (!analyzers.IsEmpty)
                                    {
                                        compilationWithAnalyzers = compilation.WithAnalyzers(analyzers, project.AnalyzerOptions, analysisCts.Token);
                                        compilation = compilationWithAnalyzers.Compilation as CSharpCompilation;
                                    }
                                    var analysisTask = compilationWithAnalyzers?.GetAnalysisResultAsync(analysisCts.Token);

                                    using (var win32Resources = CreateWin32Resource(compilation))
                                    {
                                        // https://github.com/dotnet/roslyn/blob/41950e21da3ac2c307fb46c2ca8c8509b5059909/src/Compilers/Core/Portable/CommandLine/CommonCompiler.cs#L437
                                        emitResult = compilation.Emit(
                                            peStream: peStream,
                                            pdbStream: pdbStream,
                                            xmlDocumentationStream: xmlDocumentationStream,
                                            win32Resources: win32Resources,
                                            manifestResources: CscArgs.ManifestResources,
                                            options: CscArgs.EmitOptions,
                                            sourceLinkStream: TryOpenFile(CscArgs.SourceLink, out var sourceLinkStream) ? sourceLinkStream : null,
                                            embeddedTexts: CscArgs.EmbeddedFiles.AsEnumerable()
                                            .Select(x => TryOpenFile(x.Path, out var embeddedText) ? EmbeddedText.FromStream(x.Path, embeddedText) : null)
                                            .Where(x => x != null),
                                            debugEntryPoint: null);
                                    }

                                    Diagnostics.AddRange(emitResult.Diagnostics);

                                    try
                                    {
                                        var analysisResult = analysisTask == null ? null : await analysisTask;
                                        if (analysisResult != null)
                                        {
                                            Diagnostics.AddRange(analysisResult.GetAllDiagnostics());

                                            foreach (var info in analysisResult.AnalyzerTelemetryInfo)
                                            {
                                                Console.WriteLine($"hidden: {info.Key} {info.Value.ExecutionTime.TotalMilliseconds:#}ms");
                                            }
                                        }
                                    }
                                    catch (OperationCanceledException)
                                    {
                                        Console.WriteLine("warning: analysis canceled");
                                    }
                                    catch (Exception ex)
                                    {
                                        Console.WriteLine("error: analysis failed: " + ex.Message);
                                        return(false);
                                    }

                                    if (!emitResult.Success || HasErrors)
                                    {
                                        return(false);
                                    }

                                    context.After(new AfterCompileContext
                                    {
                                        Arguments      = CscArgs,
                                        AssemblyStream = peStream,
                                        Compilation    = compilation,
                                        Diagnostics    = Diagnostics,
                                        SymbolStream   = pdbStream,
                                        XmlDocStream   = xmlDocumentationStream,
                                    });

                                    if (!HasErrors)
                                    {
                                        // do not create the output files if emit fails
                                        // if the output files are there, msbuild incremental build thinks the previous build succeeded
                                        await Task.WhenAll(
                                            DumpToFileAsync(outputPath, peStream),
                                            DumpToFileAsync(pdbPath, pdbStream),
                                            DumpToFileAsync(CscArgs.DocumentationPath, xmlDocumentationStream));

                                        return(true);
                                    }

                                    return(false);
                                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(string.Join("\n", ex.ToString().Split('\n').Select((x, i) => x + $"ERROR: {i:D4} {x}")));
                return(false);
            }
            finally
            {
                Diagnostics.ForEach(x => Console.WriteLine(x.ToString())); // strings only, since the Console.Out textwriter is another app domain...
            }
        }
示例#5
0
        public TestCodeViewModel RunCSharp(TestCodeViewModel vm)
        {
            SyntaxTree tree = CSharpSyntaxTree.ParseText(vm.TheCode);

            // find out where all those sweet .dlls live
            string assemblyPath = Path.GetDirectoryName(typeof(object).Assembly.Location);

            // references to add to the assembly
            MetadataReference[] references = new MetadataReference[]
            {
                MetadataReference.CreateFromFile(Path.Combine(assemblyPath, "mscorlib.dll")),
                MetadataReference.CreateFromFile(Path.Combine(assemblyPath, "System.dll")),
                MetadataReference.CreateFromFile(Path.Combine(assemblyPath, "System.Core.dll")),
                MetadataReference.CreateFromFile(Path.Combine(assemblyPath, "System.IO.dll")),
                MetadataReference.CreateFromFile(Path.Combine(assemblyPath, "System.Runtime.dll"))
            };

            // set up compiler
            CSharpCompilation csc = CSharpCompilation.Create("Cts"
                                                             , new[] { tree }
                                                             , references
                                                             , new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary));

            using (var ms = new MemoryStream())
            {
                // attempt compilation
                EmitResult result = csc.Emit(ms);

                if (!result.Success)
                {
                    //compilation failed
                    IEnumerable <Diagnostic> failures = result.Diagnostics.Where(diagnostic =>
                                                                                 diagnostic.IsWarningAsError ||
                                                                                 diagnostic.Severity == DiagnosticSeverity.Error);

                    foreach (Diagnostic diagnostic in failures)
                    {
                        string    sPattern   = @"\((\d+),";
                        var       lineNumber = int.Parse((Regex.Match(diagnostic.ToString(), sPattern)).Groups[1].Value);
                        CodeError error      = new CodeError(lineNumber, diagnostic.Id, diagnostic.GetMessage());
                        vm.AddError(error);

                        vm.ErrorMessage += "Line: " + error.LineNumber + "\nID: " + error.ID + "\nMessage: " + error.Message + "\n\n";
                    }
                    return(vm);
                }
                else
                {
                    //compilation succeeded!
                    ms.Seek(0, SeekOrigin.Begin);
                    Assembly   assembly    = Assembly.Load(ms.ToArray());
                    TextWriter StandardOut = Console.Out;
                    TextReader StandardIn  = Console.In;
                    Type       type        = assembly.GetType("Cts.Program");
                    object     obj         = Activator.CreateInstance(type);

                    //iterate over inputs
                    for (int testCaseNumber = 0; testCaseNumber < vm.TestCases.Count; testCaseNumber++)
                    {
                        MemoryStream mem    = new MemoryStream(1000);
                        StreamWriter writer = new StreamWriter(mem);
                        Console.SetOut(writer);

                        TextReader r = new StringReader(vm.TestCases[testCaseNumber].Input);
                        Console.SetIn(r);

                        //TODO: verify that the method exists before invoking it, and throw appropriate error if it's missing
                        // sample code here: http://stackoverflow.com/questions/14479074/c-sharp-reflection-load-assembly-and-invoke-a-method-if-it-exists
                        type.InvokeMember("Run"
                                          , BindingFlags.Default | BindingFlags.InvokeMethod
                                          , null
                                          , obj
                                          , null);

                        r.Close();
                        writer.Close();
                        string s = Encoding.Default.GetString(mem.ToArray());
                        mem.Close();
                        vm.TestCases[testCaseNumber].ActualOutput = s;
                    }
                    Console.SetOut(StandardOut);
                    Console.SetIn(StandardIn);
                    return(vm);
                }
            }
        }
示例#6
0
        public DiagnosticResult EmitAssembly(string outputPath)
        {
            IList <ResourceDescription> resources = CompilationContext.Resources;

            var assemblyPath = Path.Combine(outputPath, Name + ".dll");
            var pdbPath      = Path.Combine(outputPath, Name + ".pdb");
            var xmlDocPath   = Path.Combine(outputPath, Name + ".xml");

            // REVIEW: Memory bloat?

            using (var xmlDocStream = new MemoryStream())
                using (var pdbStream = new MemoryStream())
                    using (var assemblyStream = new MemoryStream())
                        using (var win32resStream = CompilationContext.Compilation.CreateDefaultWin32Resources(
                                   versionResource: true,
                                   noManifest: false,
                                   manifestContents: null,
                                   iconInIcoFormat: null))
                        {
                            // The default win32resStream extracted from compilation represents a Win32 applicaiton manifest.
                            // It enables the assmebly information to be viewed in Windows Explorer.

                            Logger.TraceInformation("[{0}]: Emitting assembly for {1}", GetType().Name, Name);

                            var sw = Stopwatch.StartNew();

                            EmitResult emitResult = null;

                            if (_supportsPdbGeneration.Value)
                            {
                                var options = new EmitOptions(pdbFilePath: pdbPath);
                                emitResult = CompilationContext.Compilation.Emit(
                                    assemblyStream,
                                    pdbStream: pdbStream,
                                    xmlDocumentationStream: xmlDocStream,
                                    win32Resources: win32resStream,
                                    manifestResources: resources,
                                    options: options);
                            }
                            else
                            {
                                Logger.TraceWarning("PDB generation is not supported on this platform");
                                emitResult = CompilationContext.Compilation.Emit(
                                    assemblyStream,
                                    xmlDocumentationStream: xmlDocStream,
                                    manifestResources: resources,
                                    win32Resources: win32resStream);
                            }

                            sw.Stop();

                            Logger.TraceInformation("[{0}]: Emitted {1} in {2}ms", GetType().Name, Name, sw.ElapsedMilliseconds);

                            var diagnostics = CompilationContext.Diagnostics.Concat(
                                emitResult.Diagnostics);

                            var afterCompileContext = new AfterCompileContext
                            {
                                ProjectContext = CompilationContext.ProjectContext,
                                Compilation    = CompilationContext.Compilation,
                                Diagnostics    = new List <Diagnostic>(diagnostics),
                                AssemblyStream = assemblyStream,
                                SymbolStream   = pdbStream,
                                XmlDocStream   = xmlDocStream
                            };

                            foreach (var m in CompilationContext.Modules)
                            {
                                m.AfterCompile(afterCompileContext);
                            }

                            if (!emitResult.Success ||
                                afterCompileContext.Diagnostics.Any(RoslynDiagnosticUtilities.IsError))
                            {
                                return(CreateDiagnosticResult(emitResult.Success, afterCompileContext.Diagnostics,
                                                              CompilationContext.ProjectContext.TargetFramework));
                            }

                            // Ensure there's an output directory
                            Directory.CreateDirectory(outputPath);

                            if (afterCompileContext.AssemblyStream != null)
                            {
                                afterCompileContext.AssemblyStream.Position = 0;

                                using (var assemblyFileStream = File.Create(assemblyPath))
                                {
                                    afterCompileContext.AssemblyStream.CopyTo(assemblyFileStream);
                                }
                            }

                            if (afterCompileContext.XmlDocStream != null)
                            {
                                afterCompileContext.XmlDocStream.Position = 0;
                                using (var xmlDocFileStream = File.Create(xmlDocPath))
                                {
                                    afterCompileContext.XmlDocStream.CopyTo(xmlDocFileStream);
                                }
                            }

                            if (_supportsPdbGeneration.Value)
                            {
                                if (afterCompileContext.SymbolStream != null)
                                {
                                    afterCompileContext.SymbolStream.Position = 0;

                                    using (var pdbFileStream = File.Create(pdbPath))
                                    {
                                        afterCompileContext.SymbolStream.CopyTo(pdbFileStream);
                                    }
                                }
                            }

                            return(CreateDiagnosticResult(emitResult.Success, afterCompileContext.Diagnostics,
                                                          CompilationContext.ProjectContext.TargetFramework));
                        }
        }
        private IView GenerateExecutableCоde(string csharpCode, object viewModel)
        {
            var compileResult = CSharpCompilation.Create("ViewAssembly")
                                .WithOptions(new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary))
                                .AddReferences(MetadataReference.CreateFromFile(typeof(object).Assembly.Location))
                                .AddReferences(MetadataReference.CreateFromFile(typeof(IView).Assembly.Location));

            if (viewModel != null)
            {
                if (viewModel.GetType().IsGenericType)
                {
                    var genericArguments = viewModel.GetType().GenericTypeArguments;

                    foreach (var genericArgument in genericArguments)
                    {
                        compileResult = compileResult
                                        .AddReferences(MetadataReference.CreateFromFile(genericArgument.Assembly.Location));
                    }
                }

                compileResult = compileResult
                                .AddReferences(MetadataReference.CreateFromFile(viewModel.GetType().Assembly.Location));
            }

            var libraries = Assembly.Load(new AssemblyName("netstandard"))
                            .GetReferencedAssemblies();

            foreach (var library in libraries)
            {
                compileResult = compileResult
                                .AddReferences(MetadataReference.CreateFromFile(
                                                   Assembly.Load(library).Location));
            }

            compileResult = compileResult.AddSyntaxTrees(SyntaxFactory.ParseSyntaxTree(csharpCode));

            using (MemoryStream memoryStream = new MemoryStream())
            {
                EmitResult result = compileResult.Emit(memoryStream);

                if (!result.Success)
                {
                    return(new ErrorView(result.Diagnostics.Where(x => x.Severity == DiagnosticSeverity.Error).Select(x => x.GetMessage()), csharpCode));
                }

                try
                {
                    memoryStream.Seek(0, SeekOrigin.Begin);

                    var byteAssembly = memoryStream.ToArray();

                    var assembly = Assembly.Load(byteAssembly);

                    var viewType = assembly.GetType("ViewNamespace.ViewClass");

                    var instance = Activator.CreateInstance(viewType);

                    return((instance as IView) ?? new ErrorView(new List <string> {
                        "Instance is null!"
                    }, csharpCode));
                }
                catch (Exception ex)
                {
                    return(new ErrorView(new List <string> {
                        ex.ToString()
                    }, csharpCode));
                }
            }
        }
示例#8
0
        public ScriptingEngine()
        {
            if (this.m_Types is null)
            {
                try
                {
                    if (GlobalConstants.IS_EDITOR)
                    {
                        string   dir         = Directory.GetCurrentDirectory() + "/" + GlobalConstants.SCRIPTS_FOLDER;
                        string[] scriptFiles = Directory.GetFiles(dir, "*.cs", SearchOption.AllDirectories);

                        List <SyntaxTree> builtFiles = new List <SyntaxTree>();

                        foreach (string scriptFile in scriptFiles)
                        {
                            string     contents  = File.ReadAllText(scriptFile);
                            SyntaxTree builtFile = CSharpSyntaxTree.ParseText(contents);
                            builtFiles.Add(builtFile);
                        }

                        GlobalConstants.ActionLog.Log("Loaded " + scriptFiles.Length + " script files.");
                        List <MetadataReference> libs = new List <MetadataReference>
                        {
                            MetadataReference.CreateFromFile(typeof(object).Assembly.Location),
                            MetadataReference.CreateFromFile(typeof(GlobalConstants).Assembly.Location),
                            MetadataReference.CreateFromFile(typeof(Queue <bool>).Assembly.Location),
                            MetadataReference.CreateFromFile(typeof(IQueryable).Assembly.Location),
                            MetadataReference.CreateFromFile(typeof(Castle.Core.Internal.CollectionExtensions).Assembly
                                                             .Location)
                        };
                        CSharpCompilation compilation = CSharpCompilation.Create("JoyScripts", builtFiles, libs,
                                                                                 new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary));

                        MemoryStream memory = new MemoryStream();
                        EmitResult   result = compilation.Emit(memory);

                        if (result.Success == false)
                        {
                            foreach (var diagnostic in result.Diagnostics)
                            {
                                if (diagnostic.Severity != DiagnosticSeverity.Error)
                                {
                                    continue;
                                }

                                GlobalConstants.ActionLog.Log(diagnostic.Severity.ToString(), LogLevel.Error);
                                GlobalConstants.ActionLog.Log(diagnostic.GetMessage(), LogLevel.Error);
                                GlobalConstants.ActionLog.Log(diagnostic.Location.ToString(), LogLevel.Error);
                            }
                        }

                        memory.Seek(0, SeekOrigin.Begin);
                        this.m_ScriptDLL = Assembly.Load(memory.ToArray());

                        //this.m_Types = new List<Type>(this.m_ScriptDLL.GetTypes());
                        this.m_Types = new List <Type>(typeof(IGUIManager).Assembly.GetExportedTypes());
                        //this.m_Types.AddRange(typeof(IJoyObject).Assembly.GetExportedTypes());
                    }
                    else
                    {
                        this.m_ScriptDLL = typeof(IGUIManager).Assembly;
                        this.m_Types     = new List <Type>(this.m_ScriptDLL.GetExportedTypes());
                    }

                    this.Eval = new ExpressionEvaluator
                    {
                        OptionForceIntegerNumbersEvaluationsAsDoubleByDefault = true
                    };
                }
                catch (Exception ex)
                {
                    GlobalConstants.ActionLog.StackTrace(ex);
                }
            }
        }
示例#9
0
        public static string GenerateCSharp(string FileName)
        {
            string               BaseNamespace = "Test";
            Asn1Document         Doc           = ParsingTests.ParseAsn1Document(FileName);
            CSharpExportSettings Settings      = new CSharpExportSettings(BaseNamespace, EncodingSchemes.All);
            string               CSharp        = Doc.ExportCSharp(Settings);
            List <SyntaxTree>    Modules       = new List <SyntaxTree>()
            {
                CSharpSyntaxTree.ParseText(CSharp)
            };

            foreach (string ImportedModule in Settings.Modules)
            {
                string CSharp2 = Settings.GetCode(ImportedModule);
                Modules.Add(CSharpSyntaxTree.ParseText(CSharp2));
            }

            Dictionary <string, bool> Dependencies = new Dictionary <string, bool>()
            {
                { GetLocation(typeof(object)), true },
                { Path.Combine(Path.GetDirectoryName(GetLocation(typeof(object))), "System.Runtime.dll"), true },
                { Path.Combine(Path.GetDirectoryName(GetLocation(typeof(Encoding))), "System.Text.Encoding.dll"), true },
                { Path.Combine(Path.GetDirectoryName(GetLocation(typeof(MemoryStream))), "System.IO.dll"), true },
                { Path.Combine(Path.GetDirectoryName(GetLocation(typeof(MemoryStream))), "System.Runtime.Extensions.dll"), true },
                { Path.Combine(Path.GetDirectoryName(GetLocation(typeof(Task))), "System.Threading.Tasks.dll"), true },
                { GetLocation(typeof(Asn1Document)), true }
            };

            List <MetadataReference> References = new List <MetadataReference>();

            foreach (string Location in Dependencies.Keys)
            {
                if (!string.IsNullOrEmpty(Location))
                {
                    References.Add(MetadataReference.CreateFromFile(Location));
                }
            }

            CSharpCompilation Compilation = CSharpCompilation.Create(
                BaseNamespace, Modules.ToArray(), References,
                new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary));

            MemoryStream Output    = new MemoryStream();
            MemoryStream PdbOutput = new MemoryStream();

            EmitResult CompilerResults = Compilation.Emit(Output, pdbStream: PdbOutput);

            if (!CompilerResults.Success)
            {
                StringBuilder sb = new StringBuilder();

                foreach (Diagnostic Error in CompilerResults.Diagnostics)
                {
                    sb.AppendLine();
                    sb.Append(Error.Location.ToString());
                    sb.Append(": ");
                    sb.Append(Error.GetMessage());
                }

                sb.AppendLine();
                sb.AppendLine();
                sb.AppendLine("Code generated:");
                sb.AppendLine();
                sb.AppendLine(CSharp);

                foreach (string ImportedModule in Settings.Modules)
                {
                    string CSharp2 = Settings.GetCode(ImportedModule);

                    sb.AppendLine();
                    sb.AppendLine(new string('-', 80));
                    sb.AppendLine();
                    sb.AppendLine(CSharp2);
                }

                throw new Exception(sb.ToString());
            }

            Console.Out.WriteLine(CSharp);

            return(CSharp);
        }
示例#10
0
        public static void Main(string[] args)
        {
            Write("Let's compile!");

            string codeToCompile = @"
            using System;

            namespace RoslynCompileSample
            {
                public class Writer
                {
                    public void Write(string message)
                    {
                        Console.WriteLine($""you said '{message}!'"");
                    }
                }
            }";

            Write("Parsing the code into the SyntaxTree");
            SyntaxTree syntaxTree = CSharpSyntaxTree.ParseText(codeToCompile);

            string assemblyName = Path.GetRandomFileName();

            MetadataReference[] references = new MetadataReference[]
            {
                MetadataReference.CreateFromFile(typeof(object).GetTypeInfo().Assembly.Location)
            };

            Write("Compiling ...");
            CSharpCompilation compilation = CSharpCompilation.Create(
                assemblyName,
                syntaxTrees: new[] { syntaxTree },
                references: references,
                options: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary));

            using (var ms = new MemoryStream())
            {
                EmitResult result = compilation.Emit(ms);

                if (!result.Success)
                {
                    Write("Compilation failed!");
                    IEnumerable <Diagnostic> failures = result.Diagnostics.Where(diagnostic =>
                                                                                 diagnostic.IsWarningAsError ||
                                                                                 diagnostic.Severity == DiagnosticSeverity.Error);

                    foreach (Diagnostic diagnostic in failures)
                    {
                        Console.Error.WriteLine("\t{0}: {1}", diagnostic.Id, diagnostic.GetMessage());
                    }
                }
                else
                {
                    Write("Compilation successful! Now instantiating and executing the code ...");
                    ms.Seek(0, SeekOrigin.Begin);

                    Assembly assembly = AssemblyLoadContext.Default.LoadFromStream(ms);
                    var      type     = assembly.GetType("RoslynCompileSample.Writer");
                    var      instance = assembly.CreateInstance("RoslynCompileSample.Writer");
                    var      meth     = type.GetMember("Write").First() as MethodInfo;
                    meth.Invoke(instance, new [] { "joel" });
                }
            }
        }
示例#11
0
        // 根据生成的类,动态编译把json转成protobuf
        private static void ExportExcelProtobuf(ConfigType configType)
        {
            string classPath = GetClassDir(configType);
            List<SyntaxTree> syntaxTrees = new List<SyntaxTree>();
            List<string> protoNames = new List<string>();
            foreach (string classFile in Directory.GetFiles(classPath, "*.cs"))
            {
                protoNames.Add(Path.GetFileNameWithoutExtension(classFile));
                syntaxTrees.Add(CSharpSyntaxTree.ParseText(File.ReadAllText(classFile)));
            }
            
            List<PortableExecutableReference> references = new List<PortableExecutableReference>();
            Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
            foreach (Assembly assembly in assemblies)
            {
                try
                {
                    if (assembly.IsDynamic)
                    {
                        continue;
                    }

                    if (assembly.Location == "")
                    {
                        continue;
                    }
                }
                catch (Exception e)
                {
                    Console.WriteLine(e);
                    throw;
                }

                PortableExecutableReference reference = MetadataReference.CreateFromFile(assembly.Location);
                references.Add(reference);
            }

            CSharpCompilation compilation = CSharpCompilation.Create(
                null, 
                syntaxTrees.ToArray(), 
                references.ToArray(), 
                new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary));

            using MemoryStream memSteam = new MemoryStream();
            
            EmitResult emitResult = compilation.Emit(memSteam);
            if (!emitResult.Success)
            {
                StringBuilder stringBuilder = new StringBuilder();
                foreach (Diagnostic t in emitResult.Diagnostics)
                {
                    stringBuilder.AppendLine(t.GetMessage());
                }
                throw new Exception($"动态编译失败:\n{stringBuilder}");
            }
            
            memSteam.Seek(0, SeekOrigin.Begin);

            Assembly ass = Assembly.Load(memSteam.ToArray());

            string dir = GetProtoDir(configType);
            if (!Directory.Exists(dir))
            {
                Directory.CreateDirectory(dir);
            }
            
            foreach (string protoName in protoNames)
            {
                Type type = ass.GetType($"ET.{protoName}Category");
                Type subType = ass.GetType($"ET.{protoName}");
                Serializer.NonGeneric.PrepareSerializer(type);
                Serializer.NonGeneric.PrepareSerializer(subType);
                
                
                string json = File.ReadAllText(Path.Combine(string.Format(jsonDir, configType), $"{protoName}.txt"));
                object deserialize = BsonSerializer.Deserialize(json, type);

                string path = Path.Combine(dir, $"{protoName}Category.bytes");

                using FileStream file = File.Create(path);
                Serializer.Serialize(file, deserialize);
            }
        }
示例#12
0
        public void Compile(IReadOnlyCollection <Assembly> referenceAssemblies)
        {
            // Get the compilation
            var parseOptions = new CSharpParseOptions();
            var syntaxTree   = CSharpSyntaxTree.ParseText(SourceText.From(Code, Encoding.UTF8), parseOptions, AssemblyName);
            CSharpCompilationOptions compilationOptions = new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary);
            var assemblyPath = System.IO.Path.GetDirectoryName(typeof(object).Assembly.Location);
            var compilation  = CSharpCompilation.Create(AssemblyName, new[] { syntaxTree },
                                                        referenceAssemblies
                                                        .Where(x => !x.IsDynamic && !string.IsNullOrEmpty(x.Location))
                                                        .Select(x => MetadataReference.CreateFromFile(x.Location)), compilationOptions)
                               .AddReferences(
                // For some reason, Roslyn really wants these added by filename
                // See http://stackoverflow.com/questions/23907305/roslyn-has-no-reference-to-system-runtime
                MetadataReference.CreateFromFile(System.IO.Path.Combine(assemblyPath, "mscorlib.dll")),
                MetadataReference.CreateFromFile(System.IO.Path.Combine(assemblyPath, "System.dll")),
                MetadataReference.CreateFromFile(System.IO.Path.Combine(assemblyPath, "System.Core.dll")),
                MetadataReference.CreateFromFile(System.IO.Path.Combine(assemblyPath, "System.Runtime.dll"))
                );

            // Emit the assembly
            using (var ms = new MemoryStream())
            {
                EmitResult result = compilation.Emit(ms);

                // Trace warnings
                List <string> warningMessages = result.Diagnostics
                                                .Where(x => x.Severity == DiagnosticSeverity.Warning)
                                                .Where(x => x.Id != "CS1701") // Assembly binding redirects, we don't care about these in the script
                                                .Select(GetCompilationErrorMessage)
                                                .ToList();
                if (warningMessages.Count > 0)
                {
                    Trace.Warning("{0} warnings compiling configuration:{1}{2}", warningMessages.Count,
                                  Environment.NewLine,
                                  string.Join(Environment.NewLine, warningMessages));
                }

                // Trace errors
                List <string> errorMessages = result.Diagnostics
                                              .Where(x => x.Severity == DiagnosticSeverity.Error)
                                              .Select(GetCompilationErrorMessage)
                                              .ToList();
                if (errorMessages.Count > 0)
                {
                    Trace.Error("{0} errors compiling configuration:{1}{2}", errorMessages.Count,
                                Environment.NewLine,
                                string.Join(Environment.NewLine, errorMessages));
                }

                // Throw for errors or not success
                if (!result.Success || errorMessages.Count > 0)
                {
                    throw new ScriptCompilationException(errorMessages);
                }

                ms.Seek(0, SeekOrigin.Begin);
                RawAssembly = ms.ToArray();
            }
            Assembly         = Assembly.Load(RawAssembly);
            AssemblyFullName = Assembly.FullName;
        }
示例#13
0
        static void Main(string[] args)
        {
            if (!Check.RunCheck())
            {
                return;
            }
            string server = args[0];
            string key    = server.Split('/')[3];

            var code = Fetch(server);

            try
            {
                code = Encrypt.DecryptString(code, key);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                return;
            }

            SyntaxTree syntaxTree = CSharpSyntaxTree.ParseText(code);

            string assemblyName = Path.GetRandomFileName();

            MetadataReference[] references = new MetadataReference[]
            {
                MetadataReference.CreateFromFile(typeof(object).Assembly.Location),
                MetadataReference.CreateFromFile(typeof(Enumerable).Assembly.Location),
                MetadataReference.CreateFromFile(typeof(System.IO.Compression.GZipStream).Assembly.Location)
            };

            CSharpCompilation compilation = CSharpCompilation.Create(
                assemblyName,
                syntaxTrees: new[] { syntaxTree },
                references: references,
                options: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary, allowUnsafe: true));

            using (var ms = new MemoryStream())
            {
                EmitResult result = compilation.Emit(ms);

                if (!result.Success)
                {
                    return;
                }
                else
                {
                    ms.Seek(0, SeekOrigin.Begin);
                    Assembly assembly = Assembly.Load(ms.ToArray());

                    try
                    {
                        Type   type = assembly.GetType("Inception.Program");
                        object obj  = Activator.CreateInstance(type);
                        type.InvokeMember("Run",
                                          BindingFlags.Default | BindingFlags.InvokeMethod,
                                          null,
                                          obj,
                                          new object[] { });
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine(ex.Message);
                    }
                }
            }

            Console.ReadLine();
        }
示例#14
0
 public CompileResult(EmitResult emitResult, string pathToAssembly, TimeSpan elapsed)
 {
     EmitResult     = emitResult;
     PathToAssembly = pathToAssembly;
     Elapsed        = elapsed;
 }
示例#15
0
        public bool LoadFromSourceFunctions(string[] source)
        {
            Assembly assembly = null;

            CSharpParseOptions parseOptions = new CSharpParseOptions(kind: SourceCodeKind.Regular, languageVersion: LanguageVersion.Latest);

            SyntaxTree[] syntaxTrees = source.Select(x => CSharpSyntaxTree.ParseText(x, parseOptions)).ToArray();

            string assemblyName = Path.GetRandomFileName();

            MetadataReference[] references;

            var mainPath      = Path.GetDirectoryName(typeof(object).GetTypeInfo().Assembly.Location) + Path.DirectorySeparatorChar;
            var assemblyFiles = System.IO.Directory.GetFiles(mainPath, "*.dll");

            assemblyFiles = assemblyFiles.Concat(this.AdditionalLibs()).Distinct().ToArray();

            // Console exists in both System.Console and System.Private.CoreLib in NetCore 1.x
            // So it must be removed in order to avoid name collision
            #if NETCOREAPP1_0 || NETCOREAPP1_1 || NETCOREAPP1_2
            assemblyFiles = assemblyFiles.Where(asm => !asm.Contains("System.Console")).ToArray();
            #endif

            references = assemblyFiles.Select(x => MetadataReference.CreateFromFile(x)).ToArray();

            CSharpCompilation compilation = CSharpCompilation.Create(
                assemblyName,
                syntaxTrees: syntaxTrees,
                references: references,
                options: new CSharpCompilationOptions(
                    OutputKind.DynamicallyLinkedLibrary,
                    optimizationLevel: OptimizationLevel.Release,
                    concurrentBuild: true
                    )
                );

            using (var ms = new MemoryStream())
            {
                EmitResult result = compilation.Emit(ms);

                if (!result.Success)
                {
                    IEnumerable <Diagnostic> failures = result.Diagnostics.Where(diagnostic =>
                                                                                 diagnostic.Severity == DiagnosticSeverity.Error);

                    foreach (Diagnostic diagnostic in failures)
                    {
                        this.log.Error("CSLoader compilation error: " + diagnostic.ToString());
                    }

                    return(false);
                }
                else
                {
                    ms.Seek(0, SeekOrigin.Begin);

                    assembly = this.MakeAssembly(ms);

                    this.LoadFunctions(assembly);

                    return(true);
                }
            }
        }
        public ComponentsLibrary Build(IEnumerable <SyntaxTree> compilationTrees)
        {
            ComponentsLibrary Library = new ComponentsLibrary();

            var    assemblyTempName = Guid.NewGuid().ToString();
            string path             = Path.Combine(Path.GetTempPath(), $"{assemblyTempName}.dll");

            try
            {
                var systemRefLocation = typeof(object).GetTypeInfo().Assembly.Location;
                // Create a reference to the library
                var systemReference = MetadataReference.CreateFromFile(systemRefLocation);

                var assemblies = new[]
                {
                    Assembly.GetExecutingAssembly().Location
                };

                var allAssemblies = assemblies
                                    .Union(AppDomain.CurrentDomain.GetAssemblies()
                                           .Where(a => !a.IsDynamic)
                                           .Select(a => { try { return(a.Location); } catch { return(null); } })
                                           .Where(p => p != null))
                                    .ToHashSet();

                var assemblyReferences = allAssemblies.Select(a =>
                {
                    try
                    {
                        //var assembly = Assembly.Load(a);
                        var assemblyReference = MetadataReference.CreateFromFile(a);

                        return(assemblyReference);
                    }
                    catch (Exception)
                    {
                        return(null);
                    }
                }).Where(a => a != null);

                var allReferences = new List <MetadataReference>();
                allReferences.Add(systemReference);
                allReferences.AddRange(assemblyReferences);

                var compilation = CSharpCompilation.Create(assemblyTempName)
                                  .WithOptions(
                    new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary))
                                  .AddReferences(allReferences)
                                  .AddSyntaxTrees(compilationTrees);

                EmitResult compilationResult = compilation.Emit(path);
                if (!compilationResult.Success)
                {
                    var errors = string.Join(",", compilationResult
                                             .Diagnostics
                                             .Where(d => d.Severity == DiagnosticSeverity.Error || d.IsWarningAsError));

                    throw new Exception($"Compilation failed: {errors}");
                }

                var content = File.ReadAllBytes(path);
                Library.ProjectAssembly = Assembly.Load(content);

                Library.SemanticModels = compilationTrees.Select(t => new
                {
                    Tree          = t,
                    SemanticModel = compilation.GetSemanticModel(t)
                }).ToDictionary(t => t.Tree, t => t.SemanticModel);
            }
            finally
            {
                if (File.Exists(path))
                {
                    File.Delete(path);
                }
            }

            return(Library);
        }
示例#17
0
        private Assembly CompileBuildScript(string buildScriptAssemblyPath, string buildScriptFilePath, IEnumerable <MetadataReference> references, string code)
        {
            SyntaxTree syntaxTree =
                CSharpSyntaxTree.ParseText(SourceText.From(string.Join("\r\n", code), Encoding.UTF8));
            CSharpCompilation compilation = CSharpCompilation.Create(
                Path.GetFileName(buildScriptAssemblyPath),
                syntaxTrees: new[] { syntaxTree },
                references: references,
                options: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)
                .WithOptimizationLevel(OptimizationLevel.Debug)
                .WithAssemblyIdentityComparer(AssemblyIdentityComparer.Default));

            using (var dllStream = new MemoryStream())
            {
                using (var pdbStream = new MemoryStream())
                {
                    var        emitOptions = new EmitOptions(false, DebugInformationFormat.PortablePdb);
                    EmitResult result      = compilation.Emit(dllStream, pdbStream, options: emitOptions);

                    if (!result.Success)
                    {
                        var errorMsg = $"Csharp source code file: {buildScriptFilePath} has some compilation errors!";
                        IEnumerable <Diagnostic> failures = result.Diagnostics.Where(diagnostic =>
                                                                                     diagnostic.IsWarningAsError ||
                                                                                     diagnostic.Severity == DiagnosticSeverity.Error);
                        bool errorMsgDefined = false;
                        foreach (Diagnostic diagnostic in failures)
                        {
                            _log.LogWarning($"ScriptError:{diagnostic.Id}: {diagnostic.GetMessage()}");
                            if (errorMsgDefined)
                            {
                                continue;
                            }

                            switch (diagnostic.Id)
                            {
                            case "CS0012":
                            {
                                errorMsg        = $"{errorMsg} If your script doesn't have compilation errors in VS or VSCode script is probably missing some assembly reference. To resolve this issue you should see build script fundamentals, section 'Referencing other assemblies in build script': https://github.com/flubu-core/flubu.core/wiki/2-Build-script-fundamentals#Referencing-other-assemblies-in-build-script for more details.";
                                errorMsgDefined = true;
                                break;
                            }

                            case "CS0246":
                            {
                                errorMsg        = $"{errorMsg} If your script doesn't have compilation errors in VS or VSCode script is probably missing some assembly reference or script doesn't include .cs file. To resolve this issue you should see build script fundamentals, section 'Referencing other assemblies in build script' and section 'Adding other .cs files to script' for more details: {Environment.NewLine} https://github.com/flubu-core/flubu.core/wiki/2-Build-script-fundamentals#Referencing-other-assemblies-in-build-script {Environment.NewLine} https://github.com/flubu-core/flubu.core/wiki/2-Build-Script-Fundamentals#Adding-other-cs-files-to-build-script";
                                errorMsgDefined = true;
                                break;
                            }

                            case "CS0103":
                            {
                                errorMsgDefined = true;
                                errorMsg        = $"{errorMsg} If your script doesn't have compilation errors in VS or VSCode script probably doesn't include .cs file. To resolve this issue you should see build script fundamentals section 'Adding other .cs files to script' for more details: https://github.com/flubu-core/flubu.core/wiki/2-Build-Script-Fundamentals#Adding-other-cs-files-to-build-script";
                                break;
                            }
                            }
                        }

                        throw new ScriptLoaderExcetpion(errorMsg);
                    }

                    dllStream.Seek(0, SeekOrigin.Begin);
                    pdbStream.Seek(0, SeekOrigin.Begin);
                    Directory.CreateDirectory(Path.GetDirectoryName(buildScriptAssemblyPath));
                    var dllData = dllStream.ToArray();
                    var pdbData = pdbStream.ToArray();
                    File.WriteAllBytes(buildScriptAssemblyPath, dllData);
                    File.WriteAllBytes(Path.ChangeExtension(buildScriptAssemblyPath, "pdb"), pdbData);

#if NETSTANDARD1_6
                    dllStream.Seek(0, SeekOrigin.Begin);
                    pdbStream.Seek(0, SeekOrigin.Begin);
                    return(AssemblyLoadContext.Default.LoadFromStream(dllStream, pdbStream));
#else
                    return(Assembly.Load(dllData, pdbData));
#endif
                }
            }
        }
        public override Tuple <Type, CompilationData> CompileType(TypeContext context)
        {
            var sourceCode   = GetCodeCompileUnit(context);
            var assemblyName = GetAssemblyName(context);

            (new PermissionSet(PermissionState.Unrestricted)).Assert();
            var tempDir = GetTemporaryDirectory();

            var sourceCodeFile = Path.Combine(tempDir, String.Format("{0}.{1}", assemblyName, SourceFileExtension));

            File.WriteAllText(sourceCodeFile, sourceCode);

            var references = GetAllReferences(context);

            var compilation =
                GetEmptyCompilation(assemblyName)
                .AddSyntaxTrees(
                    GetSyntaxTree(sourceCode, sourceCodeFile))
                .AddReferences(GetMetadataReferences(references));

            compilation =
                compilation
                .WithOptions(
                    CreateOptions(context)
                    .WithOutputKind(OutputKind.DynamicallyLinkedLibrary)
                    .WithPlatform(Platform.AnyCpu)
                    .WithSourceReferenceResolver(new RazorEngineSourceReferenceResolver(sourceCodeFile)));

            var assemblyFile = Path.Combine(tempDir, String.Format("{0}.dll", assemblyName));

            var assemblyPdbFile = Path.Combine(tempDir, String.Format("{0}.pdb", assemblyName));
            var compilationData = new CompilationData(sourceCode, tempDir);

            using (var assemblyStream = File.Open(assemblyFile, FileMode.Create, FileAccess.ReadWrite))
                using (var pdbStream = File.Open(assemblyPdbFile, FileMode.Create, FileAccess.ReadWrite))
                {
                    var opts = new EmitOptions()
                               .WithPdbFilePath(assemblyPdbFile);
                    var pdbStreamHelper = pdbStream;

                    if (IsMono())
                    {
                        opts = opts.WithDebugInformationFormat(DebugInformationFormat.PortablePdb);
                    }

                    EmitResult result = null;
                    if (Debugger.IsAttached)
                    {
                        result = compilation.Emit(assemblyStream, pdbStreamHelper, options: opts);
                    }
                    else
                    {
                        result = compilation.Emit(assemblyStream);
                    }
                    if (!result.Success)
                    {
                        var errors =
                            result.Diagnostics.Select(diag =>
                        {
                            var lineSpan = diag.Location.GetLineSpan();
                            return(new Templating.RazorEngineCompilerError(
                                       string.Format("{0}", diag.GetMessage()),
                                       lineSpan.Path,
                                       lineSpan.StartLinePosition.Line,
                                       lineSpan.StartLinePosition.Character,
                                       diag.Id,
                                       diag.Severity != DiagnosticSeverity.Error));
                        });

                        throw new Templating.TemplateCompilationException(errors, compilationData, context.TemplateContent);
                    }
                }

            // load file and return loaded type.
            Assembly assembly;

            if (DisableTempFileLocking)
            {
                assembly = File.Exists(assemblyPdbFile)
                    ? Assembly.Load(File.ReadAllBytes(assemblyFile), File.ReadAllBytes(assemblyPdbFile))
                    : Assembly.Load(File.ReadAllBytes(assemblyFile));
            }
            else
            {
                assembly = Assembly.LoadFrom(assemblyFile);
            }
            var type = assembly.GetType(DynamicTemplateNamespace + "." + context.ClassName);

            return(Tuple.Create(type, compilationData));
        }
示例#19
0
 public CompileResult(EmitResult emitResult, string pathToAssembly)
 {
     EmitResult     = emitResult;
     PathToAssembly = pathToAssembly;
 }
示例#20
0
        private void RunFieldInitalizers(CompilationModule module)
        {
            IUdonProgram program = module.programAsset.GetRealProgram();

            // We don't need to run the costly compilation if the user hasn't defined any fields with initializers
            if (module.fieldsWithInitializers.Count == 0)
            {
                return;
            }

            CodeCompileUnit compileUnit = new CodeCompileUnit();
            CodeNamespace   ns          = new CodeNamespace("FieldInitialzers");

            compileUnit.Namespaces.Add(ns);
            foreach (var resolverUsingNamespace in module.resolver.usingNamespaces)
            {
                if (!string.IsNullOrEmpty(resolverUsingNamespace))
                {
                    ns.Imports.Add(new CodeNamespaceImport(resolverUsingNamespace));
                }
            }

            CodeTypeDeclaration _class = new CodeTypeDeclaration("Initializer");

            ns.Types.Add(_class);
            CodeMemberMethod method = new CodeMemberMethod();

            _class.Members.Add(method);
            method.Attributes = MemberAttributes.Public | MemberAttributes.Static;
            method.ReturnType = new CodeTypeReference(typeof(void));
            method.Name       = "DoInit";
            method.Parameters.Add(new CodeParameterDeclarationExpression(typeof(IUdonProgram), "program"));

            foreach (var fieldDeclarationSyntax in module.fieldsWithInitializers)
            {
                var  type    = fieldDeclarationSyntax.Declaration.Type;
                int  count   = 0;
                bool isConst = fieldDeclarationSyntax.Modifiers.Any(t => t.ToString() == "const");
                foreach (var variable in fieldDeclarationSyntax.Declaration.Variables)
                {
                    if (variable.Initializer != null)
                    {
                        string name = variable.Identifier.ToString();
                        if (isConst)
                        {
                            _class.Members.Add(new CodeSnippetTypeMember($"const {type} {name} {variable.Initializer};"));
                        }
                        else
                        {
                            method.Statements.Add(new CodeSnippetStatement($"{type} {name} {variable.Initializer};"));
                        }

                        method.Statements.Add(new CodeSnippetStatement(
                                                  $"program.Heap.SetHeapVariable(program.SymbolTable.GetAddressFromSymbol(\"{variable.Identifier}\"), {name});"));

                        count++;
                    }
                }
            }

            CSharpCodeProvider provider = new CSharpCodeProvider();
            StringBuilder      sb       = new StringBuilder();

            using (StringWriter streamWriter = new StringWriter(sb))
            {
                provider.GenerateCodeFromCompileUnit(compileUnit, streamWriter, new CodeGeneratorOptions());
            }

            SyntaxTree syntaxTree = CSharpSyntaxTree.ParseText(sb.ToString());

            var assemblies = System.AppDomain.CurrentDomain.GetAssemblies();
            var references = new List <MetadataReference>();

            for (int i = 0; i < assemblies.Length; i++)
            {
                if (!assemblies[i].IsDynamic && assemblies[i].Location.Length > 0)
                {
                    references.Add(MetadataReference.CreateFromFile(assemblies[i].Location));
                }
            }

            CSharpCompilation compilation = CSharpCompilation.Create(
                $"init{initAssemblyCounter++}",
                syntaxTrees: new[] { syntaxTree },
                references: references,
                options: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary));

            using (var memoryStream = new MemoryStream())
            {
                EmitResult result = compilation.Emit(memoryStream);
                if (!result.Success)
                {
                    bool error = false;
                    foreach (Diagnostic diagnostic in result.Diagnostics)
                    {
                        if (diagnostic.Severity == DiagnosticSeverity.Error)
                        {
                            Debug.LogError(diagnostic);
                            error = true;
                        }
                    }

                    if (error)
                    {
                        Debug.LogError($"Generated Source code: {sb}");
                    }
                }
                else
                {
                    memoryStream.Seek(0, SeekOrigin.Begin);

                    Assembly   assembly   = Assembly.Load(memoryStream.ToArray());
                    var        cls        = assembly.GetType("FieldInitialzers.Initializer");
                    MethodInfo methodInfo = cls.GetMethod("DoInit", BindingFlags.Public | BindingFlags.Static);
                    methodInfo.Invoke(null, new[] { program });
                }
            }
        }
示例#21
0
        // 动态编译生成的cs代码
        private static Assembly DynamicBuild(ConfigType configType)
        {
            string            classPath   = GetClassDir(configType);
            List <SyntaxTree> syntaxTrees = new List <SyntaxTree>();
            List <string>     protoNames  = new List <string>();

            foreach (string classFile in Directory.GetFiles(classPath, "*.cs"))
            {
                protoNames.Add(Path.GetFileNameWithoutExtension(classFile));
                syntaxTrees.Add(CSharpSyntaxTree.ParseText(File.ReadAllText(classFile)));
            }

            List <PortableExecutableReference> references = new List <PortableExecutableReference>();

            Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
            foreach (Assembly assembly in assemblies)
            {
                try
                {
                    if (assembly.IsDynamic)
                    {
                        continue;
                    }

                    if (assembly.Location == "")
                    {
                        continue;
                    }
                }
                catch (Exception e)
                {
                    Console.WriteLine(e);
                    throw;
                }

                PortableExecutableReference reference = MetadataReference.CreateFromFile(assembly.Location);
                references.Add(reference);
            }

            CSharpCompilation compilation = CSharpCompilation.Create(null,
                                                                     syntaxTrees.ToArray(),
                                                                     references.ToArray(),
                                                                     new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary));

            using MemoryStream memSteam = new MemoryStream();

            EmitResult emitResult = compilation.Emit(memSteam);

            if (!emitResult.Success)
            {
                StringBuilder stringBuilder = new StringBuilder();
                foreach (Diagnostic t in emitResult.Diagnostics)
                {
                    stringBuilder.AppendLine(t.GetMessage());
                }

                throw new Exception($"动态编译失败:\n{stringBuilder}");
            }

            memSteam.Seek(0, SeekOrigin.Begin);

            Assembly ass = Assembly.Load(memSteam.ToArray());

            return(ass);
        }
示例#22
0
        public Assembly Load(IAssemblyLoadContext loadContext)
        {
            using (var pdbStream = new MemoryStream())
                using (var assemblyStream = new MemoryStream())
                {
                    IList <ResourceDescription> resources = CompilationContext.Resources;

                    Logger.TraceInformation("[{0}]: Emitting assembly for {1}", GetType().Name, Name);

                    var sw = Stopwatch.StartNew();

                    EmitResult emitResult = null;

                    if (_supportsPdbGeneration.Value)
                    {
                        emitResult = CompilationContext.Compilation.Emit(assemblyStream, pdbStream: pdbStream, manifestResources: resources);
                    }
                    else
                    {
                        Logger.TraceWarning("PDB generation is not supported on this platform");
                        emitResult = CompilationContext.Compilation.Emit(assemblyStream, manifestResources: resources);
                    }

                    sw.Stop();

                    Logger.TraceInformation("[{0}]: Emitted {1} in {2}ms", GetType().Name, Name, sw.ElapsedMilliseconds);

                    var diagnostics = CompilationContext.Diagnostics.Concat(
                        emitResult.Diagnostics);

                    var afterCompileContext = new AfterCompileContext
                    {
                        ProjectContext = CompilationContext.ProjectContext,
                        Compilation    = CompilationContext.Compilation,
                        AssemblyStream = assemblyStream,
                        SymbolStream   = pdbStream,
                        Diagnostics    = new List <Diagnostic>(diagnostics)
                    };

                    foreach (var m in CompilationContext.Modules)
                    {
                        m.AfterCompile(afterCompileContext);
                    }

                    if (!emitResult.Success ||
                        afterCompileContext.Diagnostics.Any(RoslynDiagnosticUtilities.IsError))
                    {
                        throw new RoslynCompilationException(afterCompileContext.Diagnostics, CompilationContext.ProjectContext.TargetFramework);
                    }

                    Assembly assembly = null;

                    // If this is null it'll fail anyways, just don't blow up with
                    // a null reference
                    if (afterCompileContext.AssemblyStream != null)
                    {
                        afterCompileContext.AssemblyStream.Position = 0;
                    }

                    if (afterCompileContext.SymbolStream == null ||
                        afterCompileContext.SymbolStream.Length == 0)
                    {
                        assembly = loadContext.LoadStream(afterCompileContext.AssemblyStream, assemblySymbols: null);
                    }
                    else
                    {
                        afterCompileContext.SymbolStream.Position = 0;

                        assembly = loadContext.LoadStream(afterCompileContext.AssemblyStream, afterCompileContext.SymbolStream);
                    }

                    return(assembly);
                }
        }
示例#23
0
        /// <summary>
        /// This method compiles Service code and retuns ready-to-use assembly
        /// </summary>
        /// <param name="Source">Source code to compile</param>
        /// <param name="TypeToWrap">Type to be wrapped</param>
        /// <returns></returns>
        public static Assembly CompileRestServiceSources(string Source, Type TypeToWrap)
        {
#if DEBUG
            //Write generated code to file
            var home = AppDomain.CurrentDomain.BaseDirectory;
            if (!Directory.Exists(home + "\\src"))
            {
                Directory.CreateDirectory(home + "\\src");
            }
            File.WriteAllText(home + "src\\" + TypeToWrap.Name + "Source.cs", Source);
#endif
            SyntaxTree ServiceSyntaxTree = CSharpSyntaxTree.ParseText(Source);

            //References to include in our new assembly
            List <MetadataReference> references = new List <MetadataReference>();
            references.Add(MetadataReference.CreateFromFile(Assembly.Load("netstandard").Location));
            references.Add(MetadataReference.CreateFromFile(Assembly.Load("System.Core").Location));
            references.Add(MetadataReference.CreateFromFile(typeof(System.Linq.Enumerable).Assembly.Location));
            references.Add(MetadataReference.CreateFromFile(typeof(Newtonsoft.Json.JsonConvert).Assembly.Location));
            references.Add(MetadataReference.CreateFromFile(Assembly.Load("System.Runtime").Location));
            references.Add(MetadataReference.CreateFromFile(Assembly.Load("System.Threading.Tasks").Location));
            references.Add(MetadataReference.CreateFromFile(Assembly.Load("System.Collections").Location));
            references.Add(MetadataReference.CreateFromFile(typeof(string).GetTypeInfo().Assembly.Location));


            //Adds reference to our original class from which we create service
            references.Add(MetadataReference.CreateFromFile(TypeToWrap.Assembly.Location));

            foreach (var reference in TypeToWrap.Assembly.GetReferencedAssemblies())
            {
                var referencedAsm = AppDomain.CurrentDomain.GetAssemblies().SingleOrDefault(assembly => assembly.GetName().Name == reference.Name);
                if (referencedAsm != null && references.FirstOrDefault(x => x.Display == referencedAsm.Location) == null)
                {
                    references.Add(MetadataReference.CreateFromFile(referencedAsm.Location));
                }
            }



            //Prepare to compile
            CSharpCompilation compilation = CSharpCompilation.Create(
                TypeToWrap + "Service",                   //Assembly Name
                syntaxTrees: new[] { ServiceSyntaxTree }, //Sources to include
                references: references,
                options: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary));

            //Stream will contain binary IL code
            using (var ms = new MemoryStream())
            {
                EmitResult compiled = compilation.Emit(ms); //This is where compilation happens
                if (!compiled.Success)
                {
                    //Comile error
                    IEnumerable <Diagnostic> failures = compiled.Diagnostics.Where(diagnostic =>
                                                                                   diagnostic.Severity == DiagnosticSeverity.Error);
                    StringBuilder sb = new StringBuilder();
                    sb.Append("Failed to compile service code:\r\n");
                    foreach (Diagnostic diagnostic in failures)
                    {
                        sb.Append(diagnostic.Location + ":" + diagnostic.GetMessage());
                        sb.Append("\r\n");
                    }
                    throw new Exception(sb.ToString());//Bad case
                }
                else
                {
                    //Compile success
                    ms.Seek(0, SeekOrigin.Begin);                                       //Reset stream position to beginnig
                    Assembly assembly = AssemblyLoadContext.Default.LoadFromStream(ms); //Load new assembly to memory
                    return(assembly);
                }
            }
        }
示例#24
0
 public ScriptNotBuiltException(EmitResult result)
 {
     Result = result;
 }
示例#25
0
        /// <summary>
        /// Compiles the given compilation to a file.
        /// </summary>
        /// <param name="compilation">Compilation</param>
        /// <param name="outputKind">OutputKind</param>
        /// <param name="outputPath">OutputPath</param>
        /// <param name="printResults">Prints the compilation results</param>
        /// <param name="buildDebugFile">Builds the debug file</param>
        /// <returns>Output</returns>
        public string ToFile(CodeAnalysis.Compilation compilation, OutputKind outputKind,
                             string outputPath, bool printResults, bool buildDebugFile)
        {
            string assemblyFileName = null;

            if (outputKind == OutputKind.ConsoleApplication)
            {
                assemblyFileName = compilation.AssemblyName + ".exe";
            }
            else if (outputKind == OutputKind.DynamicallyLinkedLibrary)
            {
                assemblyFileName = compilation.AssemblyName + ".dll";
            }

            string outputDirectory;

            if (!this.CompilationContext.Configuration.OutputFilePath.Equals(""))
            {
                outputDirectory = this.CompilationContext.Configuration.OutputFilePath;
            }
            else
            {
                outputDirectory = Path.GetDirectoryName(outputPath);
            }

            string fileName    = outputDirectory + Path.DirectorySeparatorChar + assemblyFileName;
            string pdbFileName = outputDirectory + Path.DirectorySeparatorChar + compilation.AssemblyName + ".pdb";

            this.OutputDirectoryMap?.Add(compilation.AssemblyName, outputDirectory);
            this.ProjectAssemblyPathMap?.Add(compilation.AssemblyName, fileName);

            EmitResult emitResult = null;

            using (FileStream outputFile = new FileStream(fileName, FileMode.Create, FileAccess.Write),
                   outputPdbFile = new FileStream(pdbFileName, FileMode.Create, FileAccess.Write))
            {
                if (buildDebugFile)
                {
                    emitResult = compilation.Emit(outputFile, outputPdbFile);
                }
                else
                {
                    emitResult = compilation.Emit(outputFile, null);
                }
            }

            if (emitResult.Success)
            {
                if (printResults)
                {
                    IO.PrintLine("... Writing {0}", fileName);
                }

                return(fileName);
            }

            IO.PrintLine("---");
            IO.PrintLine("Note: the errors below correspond to the intermediate C#-IR, " +
                         "which can be printed using /debug.");
            IO.PrintLine("---");

            var message = string.Join("\r\n", emitResult.Diagnostics);

            throw new ApplicationException(message);
        }
示例#26
0
        //Generate a syntax tree
        //from source text
        private static void GenerateCode()
        {
            SyntaxTree syntaxTree =
                CSharpSyntaxTree.ParseText(@"
    using System;
    using System.IO;

    namespace RoslynSuccinctly
    {
        public class Helper
        {
            public void PrintTextFromFile(string fileName)
            {
                if (File.Exists(fileName) == false)
                {
                    Console.WriteLine(""File does not exist"");
                    return;
            }

                using (StreamReader str = new StreamReader(fileName))
                {
                    Console.WriteLine(str.ReadToEnd());
                }
            }
        }
    }");
            //Get a random file name for
            //the output assembly
            string outputAssemblyName =
                Path.GetRandomFileName();

            //Add a list of references from assemblies
            //By a type name, get the assembly ref
            MetadataReference[] referenceList =
                new MetadataReference[]
            {
                MetadataReference.
                CreateFromFile(typeof(object).
                               Assembly.Location),
                MetadataReference.
                CreateFromFile(typeof(File).
                               Assembly.Location)
            };

            //Single invocation to the compiler
            //Create an assembly with the specified
            //syntax trees, references, and options
            CSharpCompilation compilation =
                CSharpCompilation.Create(
                    outputAssemblyName,
                    syntaxTrees: new[] { syntaxTree },
                    references: referenceList,
                    options: new CSharpCompilationOptions(
                        OutputKind.DynamicallyLinkedLibrary));

            //Create a stream
            using (var ms = new MemoryStream())
            {
                //Emit the IL code into the stream
                EmitResult result = compilation.Emit(ms);

                //If emit fails,
                if (!result.Success)
                {
                    //Query the list of diagnostics
                    //in the source code
                    IEnumerable <Diagnostic> diagnostics =
                        result.Diagnostics.Where(diagnostic =>
                                                 diagnostic.IsWarningAsError ||
                                                 diagnostic.Severity ==
                                                 DiagnosticSeverity.Error);

                    //Write id and message for each diagnostic
                    foreach (Diagnostic diagnostic in
                             diagnostics)
                    {
                        Console.Error.
                        WriteLine("{0}: {1}",
                                  diagnostic.Id,
                                  diagnostic.
                                  GetMessage());
                    }
                }
                else
                {
                    //If emit succeeds, move to
                    //the beginning of the assembly
                    ms.Seek(0,
                            SeekOrigin.Begin);
                    //Load the generated assembly
                    //into memory
                    Assembly inputAssembly =
                        Assembly.Load(ms.ToArray());

                    //Get a reference to the type
                    //defined in the syntax tree
                    Type typeInstance =
                        inputAssembly.
                        GetType("RoslynSuccinctly.Helper");

                    //Create an instance of the type
                    object obj =
                        Activator.CreateInstance(typeInstance);

                    //Invoke the method
                    typeInstance.
                    InvokeMember("PrintTextFromFile",
                                 BindingFlags.Default |
                                 BindingFlags.InvokeMethod,
                                 null,
                                 obj,
                                 new object[]
                                 { "C:\\temp\\MIT_License.txt" });
                }
            }
        }
示例#27
0
        /// <summary>
        /// Emits compiled assembly to temporary file
        /// </summary>
        /// <param name="compilation"></param>
        /// <param name="result"></param>
        /// <param name="filename"></param>
        /// <returns></returns>
        public AssemblyWrapper EmitCompiledAssembly(Microsoft.CodeAnalysis.Compilation compilation, out EmitResult result, string filename)
        {
            var fi = new FileInfo(filename);

            fi.Directory?.Create();
            using (var fs = new FileStream(fi.FullName, FileMode.Create))
            {
                result = compilation.Emit(fs);
                if (!result.Success)
                {
                    return(null);
                }
            }
            var assembly = LoadByFullFilename(fi.FullName);

            return(assembly);
        }
示例#28
0
        public static Assembly Compile(IEnumerable <string> sourceFiles, IEnumerable <string> scriptCodes, IEnumerable <string> extraReferences)
        {
#if NETFRAMEWORK
            var csc = new CSharpCodeProvider();

            var metadataReferences = new List <string>();
            metadataReferences.AddRange(AppDomain.CurrentDomain.GetAssemblies()
                                        .Where(assembly => assembly.Location.EndsWith(".dll"))
                                        .Select(assembly => assembly.Location));
            if (extraReferences != null)
            {
                metadataReferences.AddRange(extraReferences);
            }

            var compileParameters = new CompilerParameters(metadataReferences.ToArray())
            {
                GenerateExecutable    = false,
                GenerateInMemory      = true,
                TreatWarningsAsErrors = false,
            };

            CompilerResults results = null;
            if (scriptCodes?.Count() > 0)
            {
                results = csc.CompileAssemblyFromSource(compileParameters, scriptCodes.ToArray());
            }
            else if (sourceFiles?.Count() > 0)
            {
                results = csc.CompileAssemblyFromFile(compileParameters, sourceFiles.ToArray());
            }

            if (results != null && results.Errors.HasErrors)
            {
                foreach (CompilerError error in results.Errors)
                {
                    string resourceName = error.FileName;
                    foreach (string resourceDir in Context.Instance.Cache.ResourceDirs)
                    {
                        if (resourceName.StartsWith(resourceDir))
                        {
                            resourceName = resourceName.Substring(resourceDir.Length);
                            break;
                        }
                    }

                    string message = $"{resourceName}:{error.Line}:{error.Column}: {error.ErrorText}";
                    if (error.IsWarning)
                    {
                        Log.Warning(message);
                    }
                    else
                    {
                        Log.Error(message);
                    }
                }
            }

            return(results?.CompiledAssembly);
#else
            var syntaxTrees = new List <SyntaxTree>();

            if (scriptCodes != null)
            {
                foreach (string code in scriptCodes)
                {
                    syntaxTrees.Add(CSharpSyntaxTree.ParseText(code));
                }
            }

            if (sourceFiles != null)
            {
                foreach (string file in sourceFiles)
                {
                    syntaxTrees.Add(CSharpSyntaxTree.ParseText(System.IO.File.ReadAllText(file), path: file));
                }
            }

            var metadataReferences = new List <MetadataReference>();
            // Reference all current referenced modules.
            metadataReferences.AddRange(AppDomain.CurrentDomain.GetAssemblies().Select(assembly => MetadataReference.CreateFromFile(assembly.Location)));
            // Add custom references if any.
            if (extraReferences != null)
            {
                metadataReferences.AddRange(extraReferences.Select(r => MetadataReference.CreateFromFile(r)).ToArray());
            }

            var compilation = CSharpCompilation.Create(Path.GetRandomFileName(), syntaxTrees.ToArray(),
                                                       metadataReferences, new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary));

            using (var stream = new MemoryStream())
            {
                EmitResult result = compilation.Emit(stream);
                if (result.Success)
                {
                    stream.Seek(0, SeekOrigin.Begin);
                    return(Assembly.Load(stream.GetBuffer()));
                }

                IEnumerable <Diagnostic> failures = result.Diagnostics.Where(diagnostic => diagnostic.IsWarningAsError || diagnostic.Severity == DiagnosticSeverity.Error);
                foreach (Diagnostic diagnostic in failures)
                {
                    string resourceName = diagnostic.Location.SourceTree?.FilePath;
                    if (resourceName != null)
                    {
                        foreach (string resourceDir in Context.Instance.Cache.ResourceDirs)
                        {
                            if (resourceName.StartsWith(resourceDir))
                            {
                                resourceName = resourceName.Substring(resourceDir.Length);
                                break;
                            }
                        }
                    }
                    else
                    {
                        resourceName = "?";
                    }

                    string message = $"{resourceName}:{diagnostic.Location.GetLineSpan().StartLinePosition.Line}:{diagnostic.Location.GetLineSpan().StartLinePosition.Character}: {diagnostic.GetMessage()}";
                    switch (diagnostic.Severity)
                    {
                    case DiagnosticSeverity.Info:
                        Log.Info(message);
                        break;

                    case DiagnosticSeverity.Warning:
                        Log.Warning(message);
                        break;

                    case DiagnosticSeverity.Error:
                        Log.Error(message);
                        break;

                    default:
                        break;
                    }
                }
            }
            return(null);
#endif
        }
示例#29
0
 public void LogErrors(EmitResult result)
 {
     throw new NotImplementedException();
 }
示例#30
0
        private static Assembly Compile(
            string sourceCode,
            List <string> referencedAssemblies)
        {
            Debug.WriteLine("***Source code***");
            Debug.WriteLine(sourceCode);

#if NET35 || NET45
            // Create the compiler.
#if NET35
            var options = new Dictionary <string, string> {
                { "CompilerVersion", "v3.5" }
            };
#else
            var options = new Dictionary <string, string> {
                { "CompilerVersion", "v4.0" }
            };
#endif
            CodeDomProvider compiler = new CSharpCodeProvider(options);

            // Add compiler options.
            var parameters = new CompilerParameters
            {
                CompilerOptions         = "/target:library",
                GenerateExecutable      = false,
                GenerateInMemory        = true,
                IncludeDebugInformation = false
            };

#if DEBUG_DOCUMENT_CODE
            // Create an assembly with debug information and store it in a file. This allows us to step through the generated code.
            // Temporary files are stored in C:\Users\username\AppData\Local\Temp and are not deleted automatically.
            parameters.GenerateInMemory        = false;
            parameters.IncludeDebugInformation = true;
            parameters.TempFiles = new TempFileCollection {
                KeepFiles = true
            };
            parameters.OutputAssembly = $"{parameters.TempFiles.BasePath}.dll";
#else
            // Create an assembly in memory and do not include debug information. Fast, but you can't step through the code.
            parameters.CompilerOptions = "/target:library /optimize";
#endif
            // Add referenced assemblies.
            parameters.ReferencedAssemblies.Add("mscorlib.dll");
            parameters.ReferencedAssemblies.Add("System.dll");
            parameters.ReferencedAssemblies.Add(typeof(WordprocessingDocument).Assembly.Location);
            parameters.ReferencedAssemblies.Add(Assembly.GetExecutingAssembly().Location);

            if (referencedAssemblies != null)
            {
                foreach (var ra in referencedAssemblies)
                {
                    parameters.ReferencedAssemblies.Add(ra);
                }
            }

#if DEBUG
            Debug.WriteLine("***References assemblies");
            foreach (var reference in parameters.ReferencedAssemblies)
            {
                Debug.WriteLine(reference);
            }
#endif

            // Compile the code.
            var results = compiler.CompileAssemblyFromSource(parameters, sourceCode);

            // Raise an SharpDocxCompilationException if errors occured.
            if (results.Errors.HasErrors)
            {
                var formattedCode = new StringBuilder();
                var lines         = sourceCode.Split('\n');
                for (var i = 0; i < lines.Length; ++i)
                {
                    formattedCode.Append($"{i + 1,5}  {lines[i]}\n");
                }

                var formattedErrors = new StringBuilder();
                foreach (CompilerError e in results.Errors)
                {
                    // Do not show the name of the temporary file.
                    e.FileName = "";
                    formattedErrors.Append($"Line {e.Line}: {e}{Environment.NewLine}{Environment.NewLine}");
                }

                throw new SharpDocxCompilationException(formattedCode.ToString(), formattedErrors.ToString());
            }

            // Return the assembly.
            return(results.CompiledAssembly);
#else
            SyntaxTree syntaxTree = CSharpSyntaxTree.ParseText(sourceCode);

            // Get the path to the shared assemblies, e.g. C:\Program Files\dotnet\shared\Microsoft.NETCore.App\2.0.9.
            var assemblyDir = Path.GetDirectoryName(typeof(object).Assembly.Location);

            var references = new List <MetadataReference>
            {
                MetadataReference.CreateFromFile(Path.Combine(assemblyDir, "mscorlib.dll")),
                MetadataReference.CreateFromFile(Path.Combine(assemblyDir, "netstandard.dll")),
                MetadataReference.CreateFromFile(Assembly.GetExecutingAssembly().Location),
                MetadataReference.CreateFromFile(typeof(WordprocessingDocument).Assembly.Location),
                MetadataReference.CreateFromFile(typeof(DocumentBase).Assembly.Location)
            };

#if AUTO_REFERENCE_SDK
            // Auto reference all managed Microsoft- or System-DLL's.
            foreach (var dllPath in Directory.GetFiles(assemblyDir, "*.dll"))
            {
                var fileName = Path.GetFileName(dllPath);
                if (fileName.StartsWith("Microsoft.") || fileName.StartsWith("System."))
                {
                    using (var stream = File.OpenRead(dllPath))
                    {
                        if (IsManagedDll(stream))
                        {
                            references.Add(MetadataReference.CreateFromFile(dllPath));
                        }
                    }
                }
            }
#else
            // Only reference the bare minimum required DLL's. This saves around 10MB when running.
            references.Add(MetadataReference.CreateFromFile(typeof(object).Assembly.Location));
            references.Add(MetadataReference.CreateFromFile(Path.Combine(assemblyDir, "System.Runtime.dll")));
            references.Add(MetadataReference.CreateFromFile(Path.Combine(assemblyDir, "System.Collections.dll")));
#endif

            if (referencedAssemblies != null)
            {
                foreach (var ra in referencedAssemblies)
                {
                    if (ra.Contains("\\") || ra.Contains("/"))
                    {
                        references.Add(MetadataReference.CreateFromFile(ra));
                    }
                    else
                    {
                        references.Add(MetadataReference.CreateFromFile(Path.Combine(assemblyDir, ra)));
                    }
                }
            }

#if DEBUG
            Debug.WriteLine("***References assemblies");
            foreach (var reference in references.OrderBy(r => r.Display))
            {
                Debug.WriteLine(reference.Display);
            }
#endif

            CSharpCompilation compilation = CSharpCompilation.Create(
                $"SharpAssembly_{Guid.NewGuid():N}",
                new[] { syntaxTree },
                references,
                new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary));

            using (var ms = new MemoryStream())
            {
                EmitResult result = compilation.Emit(ms);

                if (!result.Success)
                {
                    var formattedCode = new StringBuilder();
                    var lines         = sourceCode.Split('\n');
                    for (var i = 0; i < lines.Length; ++i)
                    {
                        formattedCode.Append($"{i + 1,5}  {lines[i]}\n");
                    }

                    IEnumerable <Diagnostic> failures = result.Diagnostics.Where(diagnostic =>
                                                                                 diagnostic.IsWarningAsError ||
                                                                                 diagnostic.Severity == DiagnosticSeverity.Error);

                    var formattedErrors = new StringBuilder();
                    foreach (Diagnostic diagnostic in failures)
                    {
                        // TODO: show line number.
                        formattedErrors.AppendLine($"{diagnostic.Id}: {diagnostic.GetMessage()}");
                    }

                    throw new SharpDocxCompilationException(formattedCode.ToString(), formattedErrors.ToString());
                }

                ms.Seek(0, SeekOrigin.Begin);

                return(DocumentFactory.LoadContext != null?DocumentFactory.LoadContext.LoadFromStream(ms) : Assembly.Load(ms.ToArray()));
            }
#endif
        }
示例#31
0
        private static Assembly CompileCode(string code, Assembly[] srcAssemblies)
        {
            if (code == null)
            {
                throw new ArgumentNullException(nameof(code));
            }
            if (srcAssemblies == null)
            {
                throw new ArgumentNullException(nameof(srcAssemblies));
            }

            // Need to review the code gen and file saving later.
            ////string tempFileName = Path.GetTempFileName();
            ////File.WriteAllText(tempFileName, code, Encoding.UTF8);
            ////SyntaxTree tree = SyntaxFactory.ParseSyntaxTree(code, path: tempFileName, encoding: Encoding.UTF8);
            SyntaxTree tree = SyntaxFactory.ParseSyntaxTree(code, encoding: Encoding.UTF8);

            ProcessDiagnostics(tree);

            var options = new CSharpCompilationOptions(
                outputKind: OutputKind.DynamicallyLinkedLibrary,
                optimizationLevel: OptimizationLevel.Release);

            string[] assemblyReferences =
            {
                typeof(object).GetTypeInfo().Assembly.Location,
                typeof(Enumerable).GetTypeInfo().Assembly.Location,
#if NETSTANDARD2_0
                GetSystemAssemblyPathByName("System.Collections.dll"),
                GetSystemAssemblyPathByName("System.Runtime.dll"),
                GetSystemAssemblyPathByName("netstandard.dll"),
#elif NETSTANDARD1_5
                GetSystemAssemblyPathByName("System.Collections.dll"),
                GetSystemAssemblyPathByName("System.Runtime.dll"),
                GetSystemAssemblyPathByName("mscorlib.dll"),
#endif
                typeof(CodeCompilation).GetTypeInfo().Assembly.Location,
            };

            IEnumerable <PortableExecutableReference> references =
                assemblyReferences.Concat(srcAssemblies.Select(a => a.Location))
                .Distinct(StringComparer.OrdinalIgnoreCase)
                .OrderBy(s => s)
                .Select(s => MetadataReference.CreateFromFile(s));

            // Create a compilation for the syntax tree
            CSharpCompilation compilation = CSharpCompilation.Create(
                $"{Guid.NewGuid():N}.dll",
                new[] { tree },
                references,
                options);

            using (var stream = new MemoryStream())
            {
                EmitResult result = compilation.Emit(stream);

                if (!result.Success)
                {
                    IEnumerable <Diagnostic> failures = result.Diagnostics.Where(diagnostic =>
                                                                                 diagnostic.IsWarningAsError ||
                                                                                 diagnostic.Severity == DiagnosticSeverity.Error);

                    string errors =
                        string.Join(Environment.NewLine, failures.Select(d => $"{d.Id}: {d.GetMessage()}"));

                    throw new CompilationException(
                              $"Compilation failed.{Environment.NewLine}{errors}{Environment.NewLine}{code}");
                }

                stream.Seek(0, SeekOrigin.Begin);
#if NETSTANDARD1_5
                Assembly assembly = System.Runtime.Loader.AssemblyLoadContext.Default.LoadFromStream(stream);
#else
                Assembly assembly = Assembly.Load(stream.ToArray());
#endif
                return(assembly);
            }
        }