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); } } }
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 }
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()); }
/// <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))); }
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)); }
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); } } }
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); }
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 }
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); }
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); }
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)); }