コード例 #1
0
ファイル: CompileService.cs プロジェクト: lulzzz/ream-query
        public CompileResult LoadType(string source, string assemblyName, MetadataReference context = null)
        {
            var references = _referenceProvider.GetReferences();

            if (context != null)
            {
                references = references.Concat(new MetadataReference[] { context });
            }
            var compilerOptions = new CSharpCompilationOptions(outputKind: OutputKind.DynamicallyLinkedLibrary);
            var trees           = new SyntaxTree[] {
                CSharpSyntaxTree.ParseText(source),
            };

            LinePosition textOffset = LinePosition.Zero;

            if (context != null)
            {
                textOffset = trees.Single().GetRoot()
                             .DescendantNodes()
                             .OfType <NamespaceDeclarationSyntax>()
                             .Where(x => x.Name.ToString() == assemblyName)
                             .Last()
                             .DescendantNodes()
                             .OfType <ClassDeclarationSyntax>()
                             .Last(x => x.Identifier.ToString() == "Main")
                             .DescendantNodes()
                             .OfType <MethodDeclarationSyntax>()
                             .Single(x => x.Identifier.ToString().StartsWith("UserCodeImpl"))
                             .Body
                             .OpenBraceToken
                             .GetLocation()
                             .GetLineSpan()
                             .EndLinePosition
                ;
            }
            var compilation = CSharpCompilation.Create(assemblyName)
                              .WithOptions(compilerOptions)
                              .WithReferences(references)
                              .AddSyntaxTrees(trees);

            var compileResult     = new CompileResult();
            var stream            = new MemoryStream();
            var compilationResult = compilation.Emit(stream, options: new EmitOptions());

            stream.Position           = 0;
            compileResult.Code        = compilationResult.Success ? Api.StatusCode.Ok : Api.StatusCode.CompilationError;
            compileResult.Diagnostics = GetDiagnostics(compilationResult, textOffset.Line);

            if (compilationResult.Success)
            {
                var asm         = LibraryLoader.LoadFromStream(stream);
                var programType = asm.GetTypes().Single(t => t.Name == "Main");
                stream.Position         = 0;
                compileResult.Type      = programType;
                compileResult.Assembly  = asm;
                compileResult.Reference = MetadataReference.CreateFromStream(stream);
            }
            foreach (var diag in compilationResult.Diagnostics)
            {
                if (diag.Severity == DiagnosticSeverity.Error)
                {
                    Logger.Info("Diagnostic: {0}", diag.ToString());
                }
            }
            return(compileResult);
        }