private MetadataReference GetMetadataReference(string assetPath)
        {
            var extension = Path.GetExtension(assetPath);

            string path = assetPath;

            if (string.IsNullOrEmpty(extension) || !ValidExtensions.Any(e => e.Equals(extension, StringComparison.OrdinalIgnoreCase)))
            {
                foreach (var ext in ValidExtensions)
                {
                    path = assetPath + ext;
                    if (File.Exists(path))
                    {
                        break;
                    }
                }
            }

            AssemblyMetadata assemblyMetadata = null;

            if (!_cache.TryGetValue(path, out assemblyMetadata))
            {
                if (File.Exists(path))
                {
                    using (var stream = File.OpenRead(path))
                    {
                        var moduleMetadata = ModuleMetadata.CreateFromStream(stream, PEStreamOptions.PrefetchMetadata);
                        assemblyMetadata = AssemblyMetadata.Create(moduleMetadata);
                        _cache[path]     = assemblyMetadata;
                    }
                }
            }

            return(assemblyMetadata?.GetReference());
        }
        private static CSharpCompilation InstrumentProject(CSharpCompilation compiler, AssemblyMetadata interops, Workspace workspace)
        {
            compiler = compiler.AddReferences(interops.GetReference());
            var oldToNew = compiler.SyntaxTrees.AsParallel().WithDegreeOfParallelism(8).Where(IsNotGeneratedCode).Select(t => InstrumentTree(t, workspace));

            foreach (KeyValuePair <SyntaxTree, SyntaxTree> oldAndNew in oldToNew)
            {
                compiler = compiler.ReplaceSyntaxTree(oldAndNew.Key, oldAndNew.Value);
                Debug.Assert(oldAndNew.Value.GetText().ToString() != "{}");
            }
            return(compiler);
        }
        private static CSharpCompilation FixProject(IEnumerable <Document> documents, CSharpCompilation compiler, AssemblyMetadata interops)
        {
            compiler = compiler.AddReferences(interops.GetReference());
            var oldToNew = documents.AsParallel().WithDegreeOfParallelism(8).Select(FixDocument);

            foreach (KeyValuePair <SyntaxTree, SyntaxTree> oldAndNew in oldToNew)
            {
                compiler = compiler.ReplaceSyntaxTree(oldAndNew.Key, oldAndNew.Value);
                Debug.Assert(oldAndNew.Value.GetText().ToString() != "{}");
            }
            return(compiler);
        }
        private static MetadataReference CreateMetadataReference(string path)
        {
            using (FileStream stream = File.OpenRead(path))
            {
                ModuleMetadata moduleMetadata = ModuleMetadata
                                                .CreateFromStream(stream, PEStreamOptions.PrefetchMetadata);

                AssemblyMetadata assemblyMetadata =
                    AssemblyMetadata.Create(moduleMetadata);

                return(assemblyMetadata.GetReference(filePath: path));
            }
        }
        private MemoryStream CreateAndCompileToStream(string templateSource, RazorEngineCompilationOptions options)
        {
            templateSource = this.WriteDirectives(templateSource, options);

            RazorProjectEngine engine = RazorProjectEngine.Create(
                RazorConfiguration.Default,
                RazorProjectFileSystem.Create(@"."),
                (builder) =>
            {
                builder.SetNamespace(options.TemplateNamespace);
            });

            string fileName = Path.GetRandomFileName();

            RazorSourceDocument document = RazorSourceDocument.Create(templateSource, fileName);

            RazorCodeDocument codeDocument = engine.Process(
                document,
                null,
                new List <RazorSourceDocument>(),
                new List <TagHelperDescriptor>());

            RazorCSharpDocument razorCSharpDocument = codeDocument.GetCSharpDocument();

            SyntaxTree syntaxTree = CSharpSyntaxTree.ParseText(razorCSharpDocument.GeneratedCode);

            CSharpCompilation compilation = CSharpCompilation.Create(
                fileName,
                new[]
            {
                syntaxTree
            },
                options.ReferencedAssemblies
                .Select(ass =>
            {
#if NETSTANDARD2_0
                return(MetadataReference.CreateFromFile(ass.Location));
#else
                unsafe
                {
                    ass.TryGetRawMetadata(out byte *blob, out int length);
                    ModuleMetadata moduleMetadata                 = ModuleMetadata.CreateFromMetadata((IntPtr)blob, length);
                    AssemblyMetadata assemblyMetadata             = AssemblyMetadata.Create(moduleMetadata);
                    PortableExecutableReference metadataReference = assemblyMetadata.GetReference();

                    return(metadataReference);
                }
#endif
            })
                .Concat(options.MetadataReferences)
                .ToList(),
                new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary));

            MemoryStream memoryStream = new MemoryStream();

            EmitResult emitResult = compilation.Emit(memoryStream);

            if (!emitResult.Success)
            {
                RazorEngineCompilationException exception = new RazorEngineCompilationException()
                {
                    Errors        = emitResult.Diagnostics.ToList(),
                    GeneratedCode = razorCSharpDocument.GeneratedCode
                };

                throw exception;
            }

            memoryStream.Position = 0;

            return(memoryStream);
        }
Beispiel #6
0
        /// <summary>
        /// Use Roslyn to create an assembly.
        /// </summary>
        /// <param name="fn">File to compile. Also used for assembly name.</param>
        /// <returns></returns>
        public bool Compile(string fn)
        {
            CompiledAssembly = null;
            Errors.Clear();

            string sc          = File.ReadAllText(fn);
            string newAssyName = Path.GetFileNameWithoutExtension(fn);

            // Assemble references.
            var mr = new List <MetadataReference>();

            // Remarks:
            //     Performance considerations:
            //     It is recommended to use Microsoft.CodeAnalysis.AssemblyMetadata.CreateFromFile(System.String)
            //     API when creating multiple references to the same assembly. Reusing Microsoft.CodeAnalysis.AssemblyMetadata
            //     object allows for sharing data across these references.

            //var myAssy = Assembly.GetExecutingAssembly();
            //var refAssys = myAssy.GetReferencedAssemblies();

            // Add reference to almost everything we have loaded now.
            var           loadedAssemblies = AppDomain.CurrentDomain.GetAssemblies();
            List <string> ignore           = new List <string> {
                "Dex9.exe", "Microsoft.CodeAnalysis.dll", "Microsoft.CodeAnalysis.CSharp.dll"
            };

            foreach (var lassy in loadedAssemblies)
            {
                string loc = lassy.Location;

                if (ignore.TrueForAll(i => !loc.Contains(i)))
                {
                    Debug.WriteLine(loc);
                    AssemblyMetadata amd = AssemblyMetadata.CreateFromFile(loc);
                    mr.Add(amd.GetReference());
                }
            }

            // Parse the source.
            SyntaxTree syntaxTree                = CSharpSyntaxTree.ParseText(sc);
            CSharpCompilationOptions opts        = new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary);
            CSharpCompilation        compilation = CSharpCompilation.Create(newAssyName, new[] { syntaxTree }, mr, opts);

            // Compile the source.
            using (var memoryStream = new MemoryStream())
            {
                var result = compilation.Emit(memoryStream);

                if (result.Success)
                {
                    memoryStream.Seek(0, SeekOrigin.Begin);
                    CompiledAssembly = Assembly.Load(memoryStream.ToArray());
                }
                else
                {
                    foreach (var diag in result.Diagnostics)
                    {
                        Errors.Add(FormatDiagnostic(diag, fn));
                    }
                }
            }

            return(Errors.Count == 0 && CompiledAssembly != null);
        }