Esempio n. 1
0
        private void AddAsseblyReference(List <MetadataImageReference> assemblies, HashSet <AssemblyIdentity> added, AssemblyIdentity assemblyIdentity)
        {
            if (added.Contains(assemblyIdentity))
            {
                return;
            }

            var resolvedFilePath = this.ResolveAssemblyReferense(assemblyIdentity);

            if (resolvedFilePath == null)
            {
                Console.WriteLine("Error: Can't resolve reference: " + assemblyIdentity);
                return;
            }

            var metadata = AssemblyMetadata.CreateFromStream(new FileStream(resolvedFilePath, FileMode.Open, FileAccess.Read));

            if (added.Add(metadata.GetAssembly().Identity))
            {
                assemblies.Add(new MetadataImageReference(metadata, new MetadataReferenceProperties(), null, resolvedFilePath, null));

                this.LoadAssemblySymbol(metadata, true);

                // process nested
                foreach (var refAssemblyIdentity in metadata.GetAssembly().AssemblyReferences)
                {
                    this.AddAsseblyReference(assemblies, added, refAssemblyIdentity);
                }
            }
        }
Esempio n. 2
0
        public virtual void AddReferenceFromName(string name)
        {
            if (!_isInitialized)
            {
                InitializeReferences();
            }

#if DNX451 || DNXCORE50
            var libraryExport = CompilationServices.Default.LibraryExporter.GetExport(name);
            if (libraryExport != null)
            {
                foreach (var metadataReference in libraryExport.MetadataReferences)
                {
                    var roslynReference = metadataReference as IRoslynMetadataReference;
                    if (roslynReference != null)
                    {
                        _references.Add(roslynReference.MetadataReference);
                        return;
                    }

                    var fileMetadataReference = metadataReference as IMetadataFileReference;
                    if (fileMetadataReference != null)
                    {
                        var metadata = AssemblyMetadata.CreateFromStream(File.OpenRead(fileMetadataReference.Path));
                        _references.Add(metadata.GetReference());
                        return;
                    }
                }
            }

            throw new InvalidOperationException("Unable to create metadata reference from name: " + name);
#else
            _references.Add(MetadataReference.CreateFromFile(Assembly.Load(name).Location));
#endif
        }
Esempio n. 3
0
        internal Metadata GetMetadata(string fullPath)
        {
            var timestamp = GetFileTimeStamp(fullPath);

            // Check if we have an entry in the dictionary.
            if (_metadataCache.TryGetValue(fullPath, out var entry))
            {
                if (timestamp.HasValue && timestamp.Value == entry.Timestamp)
                {
                    // The file has not changed since we cached it. Return the cached entry.
                    return(entry.Metadata);
                }
                else
                {
                    // The file has changed recently. Remove the cache entry.
                    _metadataCache.Remove(fullPath);
                }
            }

            Metadata metadata;

            using (var fileStream = File.OpenRead(fullPath))
            {
                metadata = AssemblyMetadata.CreateFromStream(fileStream, PEStreamOptions.PrefetchMetadata);
            }

            _metadataCache.GetOrAdd(fullPath, new MetadataCacheEntry(timestamp.Value, metadata));

            return(metadata);
        }
        private MetadataReference CreateMetadataFileReference(string path)
        {
            var metadata = _metadataFileCache.GetOrAdd(path, _ =>
            {
                return(AssemblyMetadata.CreateFromStream(File.OpenRead(path)));
            });

            return(metadata.GetReference());
        }
Esempio n. 5
0
        /// <summary>
        /// </summary>
        /// <param name="assemblyIdentity">
        /// </param>
        /// <returns>
        /// </returns>
        private AssemblyMetadata GetAssemblyMetadata(AssemblyIdentity assemblyIdentity)
        {
            var resolveReferencePath = this.ResolveAssemblyReferense(assemblyIdentity);

            if (string.IsNullOrWhiteSpace(resolveReferencePath))
            {
                return(null);
            }

            return(AssemblyMetadata.CreateFromStream(new FileStream(resolveReferencePath, FileMode.Open, FileAccess.Read)));
        }
Esempio n. 6
0
        public static TestMetadataReferenceInfo Create(Compilation compilation, string fullPath, EmitOptions emitOptions)
        {
            var emitStream = compilation.EmitToStream(emitOptions);

            var metadata          = AssemblyMetadata.CreateFromStream(emitStream);
            var metadataReference = new TestMetadataReference(metadata, fullPath: fullPath);

            return(new TestMetadataReferenceInfo(
                       emitStream,
                       compilation,
                       metadataReference,
                       fullPath));
        }
Esempio n. 7
0
        private void AddAsseblyReference(List <MetadataImageReference> assemblies, HashSet <AssemblyIdentity> added, string resolvedFilePath)
        {
            var metadata = AssemblyMetadata.CreateFromStream(new FileStream(resolvedFilePath, FileMode.Open, FileAccess.Read));

            if (added.Add(metadata.GetAssembly().Identity))
            {
                assemblies.Add(new MetadataImageReference(metadata, new MetadataReferenceProperties(), null, resolvedFilePath, null));

                this.LoadAssemblySymbol(metadata, true);

                // process nested
                foreach (var refAssemblyIdentity in metadata.GetAssembly().AssemblyReferences)
                {
                    this.AddAsseblyReference(assemblies, added, refAssemblyIdentity);
                }
            }
        }
Esempio n. 8
0
        private AssemblyMetadata CompileInMemory(string[] source)
        {
            var assemblyName = Path.GetFileNameWithoutExtension(this.FirstSource);

            var dllStream = new MemoryStream();

            using (var pdbStream = new MemoryStream())
            {
                if (CompileTo(source, dllStream, pdbStream))
                {
                    // reset stream
                    dllStream.Flush();
                    dllStream.Position = 0;

                    return(AssemblyMetadata.CreateFromStream(dllStream, false));
                }
            }

            return(null);
        }
Esempio n. 9
0
        public virtual void AddReferenceFromName([NotNull] string name)
        {
            Check.NotEmpty(name, nameof(name));

            if (!_isInitialized)
            {
                InitializeReferences();
            }

#if DNX451 || DNXCORE50
            var libraryManager = _serviceProvider.GetRequiredService <ILibraryManager>();
            var libraryExport  = libraryManager.GetLibraryExport(name);
            if (libraryExport != null)
            {
                foreach (var metadataReference in libraryExport.MetadataReferences)
                {
                    var roslynReference = metadataReference as IRoslynMetadataReference;
                    if (roslynReference != null)
                    {
                        _references.Add(roslynReference.MetadataReference);
                        return;
                    }

                    var fileMetadataReference = metadataReference as IMetadataFileReference;
                    if (fileMetadataReference != null)
                    {
                        var metadata = AssemblyMetadata.CreateFromStream(File.OpenRead(fileMetadataReference.Path));
                        _references.Add(metadata.GetReference());
                        return;
                    }
                }
            }

            throw new InvalidOperationException(Strings.UnableToCreateMetadataReference(name));
#else
            _references.Add(MetadataReference.CreateFromFile(Assembly.Load(name).Location));
#endif
        }
Esempio n. 10
0
        public void CompilationReferences_Less()
        {
            // Add some references that are actually not used in the source.
            // The only actual reference stored in the metadata image would be: mscorlib (rowid 1).
            // If we incorrectly assume the references are the same we will map TypeRefs of
            // Mscorlib to System.Windows.Forms.
            var references = new[] { SystemWindowsFormsRef, MscorlibRef, SystemCoreRef };

            string src1 = @"
using System;
using System.Threading.Tasks;

class C 
{ 
    public Task<int> F() { Console.WriteLine(123); return null; }
    public static void Main() { Console.WriteLine(1); } 
}
";
            string src2 = @"
using System;
using System.Threading.Tasks;

class C 
{ 
    public Task<int> F() { Console.WriteLine(123); return null; }
    public static void Main() { Console.WriteLine(2); }
}
";

            var c1       = CreateCompilation(src1, references);
            var c2       = c1.WithSource(src2);
            var md1      = AssemblyMetadata.CreateFromStream(c1.EmitToStream());
            var baseline = EmitBaseline.CreateInitialBaseline(md1.GetModules()[0], handle => default(EditAndContinueMethodDebugInformation));

            var mdStream       = new MemoryStream();
            var ilStream       = new MemoryStream();
            var pdbStream      = new MemoryStream();
            var updatedMethods = new List <MethodDefinitionHandle>();

            var edits = new[]
            {
                new SemanticEdit(
                    SemanticEditKind.Update,
                    c1.GlobalNamespace.GetMember <NamedTypeSymbol>("C").GetMember("Main"),
                    c2.GlobalNamespace.GetMember <NamedTypeSymbol>("C").GetMember("Main"))
            };

            c2.EmitDifference(baseline, edits, mdStream, ilStream, pdbStream, updatedMethods);

            var actualIL   = ImmutableArray.Create(ilStream.ToArray()).GetMethodIL();
            var expectedIL = @"
{
  // Code size        7 (0x7)
  .maxstack  8
  IL_0000:  ldc.i4.2
  IL_0001:  call       0x0A000006
  IL_0006:  ret
}";

            // If the references are mismatched then the symbol matcher won't be able to find Task<T>
            // and will recompile the method body of F (even though the method hasn't changed).
            AssertEx.AssertEqualToleratingWhitespaceDifferences(expectedIL, actualIL);
        }
Esempio n. 11
0
        public void CompilationReferences_More()
        {
            string src1 = @"
using System;
class C 
{ 
    public static int F(object a) { return 1; }
    public static void Main() { Console.WriteLine(F(null)); } 
}
";
            string src2 = @"
using System;
class C 
{ 
    public static int F(object a) { return 1; }
    public static void Main() { F(null); }
}
";

            // Let's say an IL rewriter inserts a new overload of F that references
            // a type in a new AssemblyRef.
            string srcPE = @"
using System;
class C 
{ 
    public static int F(System.Diagnostics.Process a) { return 2; }
    public static int F(object a) { return 1; }

    public static void Main() { F(null); }
}
";
            var    md1   = AssemblyMetadata.CreateFromStream(CreateCompilation(srcPE, new[] { MscorlibRef, SystemRef }).EmitToStream());

            var c1       = CreateCompilation(src1, new[] { MscorlibRef });
            var c2       = c1.WithSource(src2);
            var baseline = EmitBaseline.CreateInitialBaseline(md1.GetModules()[0], handle => default(EditAndContinueMethodDebugInformation));

            var mdStream       = new MemoryStream();
            var ilStream       = new MemoryStream();
            var pdbStream      = new MemoryStream();
            var updatedMethods = new List <MethodDefinitionHandle>();

            var edits = new[]
            {
                new SemanticEdit(
                    SemanticEditKind.Update,
                    c1.GlobalNamespace.GetMember <NamedTypeSymbol>("C").GetMember("Main"),
                    c2.GlobalNamespace.GetMember <NamedTypeSymbol>("C").GetMember("Main"))
            };

            c2.EmitDifference(baseline, edits, mdStream, ilStream, pdbStream, updatedMethods);

            var actualIL = ImmutableArray.Create(ilStream.ToArray()).GetMethodIL();

            // Symbol matcher should ignore overloads with missing type symbols and match
            // F(object).
            var expectedIL = @"
{
  // Code size        8 (0x8)
  .maxstack  8
  IL_0000:  ldnull
  IL_0001:  call       0x06000002
  IL_0006:  pop
  IL_0007:  ret
}";

            AssertEx.AssertEqualToleratingWhitespaceDifferences(expectedIL, actualIL);
        }
Esempio n. 12
0
        private AssemblyMetadata CompileWithRoslynInMemory(string[] source)
        {
            var srcFileName  = Path.GetFileNameWithoutExtension(this.FirstSource);
            var assemblyName = srcFileName;

            var defineSeparators = new[] { ';', ' ' };
            var syntaxTrees      =
                source.Select(
                    s =>
                    CSharpSyntaxTree.ParseText(
                        SourceText.From(new FileStream(s, FileMode.Open, FileAccess.Read), Encoding.UTF8),
                        new CSharpParseOptions(
                            LanguageVersion.Latest,
                            preprocessorSymbols: this.Options["DefineConstants"].Split(defineSeparators, StringSplitOptions.RemoveEmptyEntries)),
                        s));

            var assemblies = new List <MetadataImageReference>();

            this.Assemblies = this.LoadReferencesForCompiling(assemblies);

            var options =
                new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary).WithAllowUnsafe(true)
                .WithOptimizationLevel(DebugOutput ? OptimizationLevel.Debug : OptimizationLevel.Release)
                .WithConcurrentBuild(true);

            var compilation = CSharpCompilation.Create(assemblyName, syntaxTrees, assemblies.ToArray(), options);

            var dllStream = new MemoryStream();
            var pdbStream = new MemoryStream();

            PEModuleBuilder.OnMethodBoundBodySynthesizedDelegate peModuleBuilderOnOnMethodBoundBodySynthesized = (symbol, body) =>
            {
                var key = symbol.ToKeyString();
                Debug.Assert(!this.boundBodyByMethodSymbol.ContainsKey(key), "Check if method is partial");
                this.boundBodyByMethodSymbol[key] = body;
            };

            PEModuleBuilder.OnSourceMethodDelegate peModuleBuilderOnSourceMethod = (symbol, sourceMethod) =>
            {
                var key = symbol.ToKeyString();
                Debug.Assert(!this.sourceMethodByMethodSymbol.ContainsKey(key), "Check if method is partial");
                this.sourceMethodByMethodSymbol[key] = sourceMethod;
            };

            PEModuleBuilder.OnMethodBoundBodySynthesized += peModuleBuilderOnOnMethodBoundBodySynthesized;
            PEModuleBuilder.OnSourceMethod += peModuleBuilderOnSourceMethod;

            var result = compilation.Emit(peStream: dllStream, pdbStream: pdbStream);

            PEModuleBuilder.OnMethodBoundBodySynthesized -= peModuleBuilderOnOnMethodBoundBodySynthesized;
            PEModuleBuilder.OnSourceMethod -= peModuleBuilderOnSourceMethod;

            if (result.Diagnostics.Length > 0)
            {
                var errors = result.Diagnostics.Where(d => d.Severity == DiagnosticSeverity.Error).ToList();
                Console.WriteLine(@"Errors: {0}", errors.Count);
                foreach (var diagnostic in errors)
                {
                    Console.WriteLine(diagnostic);
                }

                var diagnostics = result.Diagnostics.Where(d => d.Severity != DiagnosticSeverity.Error);
                Console.WriteLine(@"Warnings/Info: {0}", diagnostics.Count());
                foreach (var diagnostic in diagnostics)
                {
                    Console.WriteLine(diagnostic);
                }

                if (errors.Count > 0)
                {
                    return(null);
                }
            }

            dllStream.Flush();
            dllStream.Position = 0;

            pdbStream.Flush();
            pdbStream.Position = 0;

            // Successful Compile
            return(AssemblyMetadata.CreateFromStream(dllStream, false));
        }