提交 06979fd8 编写于 作者: T TomasMatousek

AssemblyMetadata and ModuleMetadata factories should not read the content of...

 AssemblyMetadata and ModuleMetadata factories should not read the content of the PE file/metadata blob.

     Currently the factories read the headers, Assembly and Modules tables, which might result in BadImageFormatException being thrown. This exception is not turned into a compilation diagnostic because it happens before the compilation is created. A user of the Roslyn API thus needs to handle these errors in two places (as an exception and as a diagnostics). The content reading should be deferred until the AssemblyMetadata/ModuleMetadata is queried for content.

     This change defers metadata/PE headers reading and decoding until the AssemblyMetadata and ModuleMetadata properties/methods are called.
     For metadata created from files it aims to match the usage pattern of other APIs working with FileStream. The metadata factory opens the file, which might throw IO exception, but doesn't start reading the stream until the compiler asks for it, therefore it doesn't throw BadImageFormatException. The functionality is equivalent to the user opening a FileStream and creating metadata from that stream (except for a slight complication with multi-module assemblies, which are rare). Thus the API for metadata creation are consistent among in-memory byte array, stream, and file path.  (changeset 1342462)
上级 8e33e984
......@@ -237,7 +237,7 @@ public PEAssemblySymbol CreatePEAssemblyForAssemblyMetadata(AssemblyMetadata met
referencedAssembliesByIdentity.Add(symbol.Identity, symbol);
}
var assembly = metadata.Assembly;
var assembly = metadata.GetAssembly();
var peReferences = assembly.AssemblyReferences.SelectAsArray(MapAssemblyIdentityToResolvedSymbol, referencedAssembliesByIdentity);
var assemblySymbol = new PEAssemblySymbol(assembly, DocumentationProvider.Default, isLinked: false, importOptions: importOptions);
......
......@@ -947,7 +947,7 @@ class Program
var exeMetadata = AssemblyMetadata.CreateFromImage(consoleappCompilation.EmitToArray());
peModule = exeMetadata.Assembly.ManifestModule;
peModule = exeMetadata.GetAssembly().ManifestModule;
metadataReader = peModule.GetMetadataReader();
Assert.Equal(1, metadataReader.GetTableRowCount(TableIndex.ModuleRef));
......
......@@ -53,7 +53,7 @@ class C
var c1 = CreateCompilation(src1, references);
var c2 = CreateCompilation(src2, references);
var md1 = AssemblyMetadata.CreateFromImageStream(c1.EmitToStream());
var baseline = EmitBaseline.CreateInitialBaseline(md1.ManifestModule, handle => ImmutableArray.Create<string>());
var baseline = EmitBaseline.CreateInitialBaseline(md1.GetModules()[0], handle => ImmutableArray.Create<string>());
var mdStream = new MemoryStream();
var ilStream = new MemoryStream();
......@@ -122,7 +122,7 @@ class C
var c1 = CreateCompilation(src1, new[] { MscorlibRef });
var c2 = CreateCompilation(src2, new[] { MscorlibRef });
var baseline = EmitBaseline.CreateInitialBaseline(md1.ManifestModule, handle => ImmutableArray.Create<string>());
var baseline = EmitBaseline.CreateInitialBaseline(md1.GetModules()[0], handle => ImmutableArray.Create<string>());
var mdStream = new MemoryStream();
var ilStream = new MemoryStream();
......
......@@ -3934,7 +3934,7 @@ static object F()
var compilation0 = CreateCompilationWithMscorlib(source0, options: TestOptions.DebugDll);
var compilation1 = CreateCompilationWithMscorlib(source1, options: TestOptions.DebugDll);
var moduleMetadata0 = ((AssemblyMetadata)metadata0.GetMetadata()).Modules[0];
var moduleMetadata0 = ((AssemblyMetadata)metadata0.GetMetadata()).GetModules()[0];
var method0 = compilation0.GetMember<MethodSymbol>("C.F");
var generation0 = EmitBaseline.CreateInitialBaseline(
moduleMetadata0,
......@@ -4623,7 +4623,7 @@ static object F(System.IDisposable d)
var compilation0 = CreateCompilationWithMscorlib(source, options: TestOptions.DebugDll);
var compilation1 = CreateCompilationWithMscorlib(source, options: TestOptions.DebugDll);
var moduleMetadata0 = ((AssemblyMetadata)metadata0.GetMetadata()).Modules[0];
var moduleMetadata0 = ((AssemblyMetadata)metadata0.GetMetadata()).GetModules()[0];
var method0 = compilation0.GetMember<MethodSymbol>("C.F");
var generation0 = EmitBaseline.CreateInitialBaseline(
moduleMetadata0,
......
......@@ -245,7 +245,7 @@ public void AssemblyRefs_DuplicateRows()
context.Diagnostics.Verify();
// check that there are no duplicate rows in AssemblyRef table:
PEAssembly emittedAssembly = AssemblyMetadata.CreateFromImage(image).Assembly;
PEAssembly emittedAssembly = AssemblyMetadata.CreateFromImage(image).GetAssembly();
var emittedReferences = emittedAssembly.Modules[0].ReferencedAssemblies;
Assert.Equal(1, emittedReferences.Length);
Assert.Equal("foo", emittedReferences[0].Name);
......
......@@ -1683,7 +1683,7 @@ public class PrintTicket
AssemblyIdentity actualIdentity = method.ReturnType.ContainingAssembly.Identity;
// Even though the compilation has the correct version number, the referenced binary is preferred.
Assert.Equal(oldMetadata.Assembly.Identity, actualIdentity);
Assert.Equal(oldMetadata.GetAssembly().Identity, actualIdentity);
Assert.NotEqual(comp.Assembly.Identity, actualIdentity);
}
......@@ -1802,7 +1802,7 @@ class D
Assert.Equal(comp1.Assembly, moduleSymbol1.ContainingAssembly);
var moduleReferences1 = moduleSymbol1.GetReferencedAssemblies();
Assert.Contains(assemblyMetadata.Assembly.Identity, moduleReferences1);
Assert.Contains(assemblyMetadata.GetAssembly().Identity, moduleReferences1);
var moduleTypeSymbol1 = comp1.GlobalNamespace.GetMember<NamedTypeSymbol>("TypeFromModule");
Assert.Equal(moduleSymbol1, moduleTypeSymbol1.ContainingModule);
......
......@@ -111,7 +111,7 @@ private ObjectReference GetWeakAssemblyFromCache(FileKey fileKey)
Assert.Equal(2, mdTestLib1.CachedSymbols.Count());
object assembly = mdTestLib1.Metadata.GetTarget().Assembly;
object assembly = mdTestLib1.Metadata.GetTarget().GetAssembly();
Assert.NotNull(assembly);
return new ObjectReference(assembly);
}
......@@ -176,7 +176,7 @@ public void CompilationWithMscorlibReference()
Assert.Equal(mscorlibPath, MetadataCache.AssembliesFromFiles.Keys.Single().FullPath, StringComparer.OrdinalIgnoreCase);
var assembly = cachedAssembly.Metadata.GetTarget().Assembly;
var assembly = cachedAssembly.Metadata.GetTarget().GetAssembly();
Assert.NotNull(assembly);
Assert.Equal("mscorlib", assembly.Identity.Name);
......@@ -188,7 +188,7 @@ public void CompilationWithMscorlibReference()
var mscorlibAsm = (PEAssemblySymbol)cachedAssembly.CachedSymbols.First();
Assert.NotNull(mscorlibAsm);
Assert.Same(mscorlibAsm.Assembly, cachedAssembly.Metadata.GetTarget().Assembly);
Assert.Same(mscorlibAsm.Assembly, cachedAssembly.Metadata.GetTarget().GetAssembly());
Assert.Equal("mscorlib", mscorlibAsm.Identity.Name);
Assert.Equal("mscorlib", mscorlibAsm.Name);
Assert.Equal(1, mscorlibAsm.Modules.Length);
......@@ -583,7 +583,7 @@ public void ReferenceModule()
Assert.Same(mscorlibInfo.CachedSymbols.First(), mscorlibAsm);
var varMTTestLib1Info = MetadataCache.AssembliesFromFiles[FileKey.Create(varMTTestLib1Path)];
var assembly = varMTTestLib1Info.Metadata.GetTarget().Assembly;
var assembly = varMTTestLib1Info.Metadata.GetTarget().GetAssembly();
Assert.NotNull(assembly);
Assert.Equal(1, varMTTestLib1Info.CachedSymbols.Count());
......@@ -850,7 +850,7 @@ public void ReferenceMultiModuleAssembly()
var fileInfo = MetadataCache.AssembliesFromFiles[FileKey.Create(multimoduleRef.FilePath)];
var assembly = fileInfo.Metadata.GetTarget().Assembly;
var assembly = fileInfo.Metadata.GetTarget().GetAssembly();
// tc1 compilation is holding on the Assembly:
Assert.NotNull(assembly);
......@@ -1336,7 +1336,7 @@ public void CompactFileCache2()
lock (MetadataCache.Guard)
{
Assert.Equal(1, mdTestLib1.CachedSymbols.Count());
Assert.NotNull(mdTestLib1.Metadata.GetTarget().Assembly);
Assert.NotNull(mdTestLib1.Metadata.GetTarget().GetAssembly());
Assert.False(mdTestLib1.CachedSymbols.GetWeakReference(0).IsNull());
Assert.Same(mdTestLib1.Metadata, MetadataCache.AssembliesFromFiles[fileKey].Metadata);
......
......@@ -42,8 +42,8 @@ public void CreateFromBytes()
using (var a = AssemblyMetadata.CreateFromImage(TestResources.SymbolsTests.MultiModule.MultiModule))
{
// even though the image refers to other modules only the manifest module is loaded:
Assert.Equal(1, a.Modules.Length);
Assert.Equal("MultiModule.dll", a.Modules[0].Name);
Assert.Equal(1, a.GetModules().Length);
Assert.Equal("MultiModule.dll", a.GetModules()[0].Name);
}
}
......@@ -57,10 +57,10 @@ public void CreateFromFile()
using (var a = MetadataFileFactory.CreateAssembly(mm))
{
Assert.Equal(3, a.Modules.Length);
Assert.Equal("MultiModule.dll", a.Modules[0].Name);
Assert.Equal("mod2.netmodule", a.Modules[1].Name);
Assert.Equal("mod3.netmodule", a.Modules[2].Name);
Assert.Equal(3, a.GetModules().Length);
Assert.Equal("MultiModule.dll", a.GetModules()[0].Name);
Assert.Equal("mod2.netmodule", a.GetModules()[1].Name);
Assert.Equal("mod3.netmodule", a.GetModules()[2].Name);
}
}
......@@ -96,54 +96,53 @@ public void ImageOwnership()
var copy1 = a.Copy();
Assert.False(copy1.IsImageOwner, "Assembly should not own the image");
Assert.False(copy1.Modules[0].IsImageOwner, "Module should not own the image");
Assert.False(copy1.Modules[1].IsImageOwner, "Module should not own the image");
Assert.False(copy1.Modules[2].IsImageOwner, "Module should not own the image");
Assert.False(copy1.GetModules()[0].IsImageOwner, "Module should not own the image");
Assert.False(copy1.GetModules()[1].IsImageOwner, "Module should not own the image");
Assert.False(copy1.GetModules()[2].IsImageOwner, "Module should not own the image");
Assert.Equal(m1.Module, copy1.Modules[0].Module);
Assert.Equal(m2.Module, copy1.Modules[1].Module);
Assert.Equal(m3.Module, copy1.Modules[2].Module);
Assert.Equal(m1.Module, copy1.GetModules()[0].Module);
Assert.Equal(m2.Module, copy1.GetModules()[1].Module);
Assert.Equal(m3.Module, copy1.GetModules()[2].Module);
var copy2 = copy1.Copy();
Assert.False(copy2.IsImageOwner, "Assembly should not own the image");
Assert.False(copy2.Modules[0].IsImageOwner, "Module should not own the image");
Assert.False(copy2.Modules[1].IsImageOwner, "Module should not own the image");
Assert.False(copy2.Modules[2].IsImageOwner, "Module should not own the image");
Assert.False(copy2.GetModules()[0].IsImageOwner, "Module should not own the image");
Assert.False(copy2.GetModules()[1].IsImageOwner, "Module should not own the image");
Assert.False(copy2.GetModules()[2].IsImageOwner, "Module should not own the image");
Assert.Equal(m1.Module, copy2.Modules[0].Module);
Assert.Equal(m2.Module, copy2.Modules[1].Module);
Assert.Equal(m3.Module, copy2.Modules[2].Module);
Assert.Equal(m1.Module, copy2.GetModules()[0].Module);
Assert.Equal(m2.Module, copy2.GetModules()[1].Module);
Assert.Equal(m3.Module, copy2.GetModules()[2].Module);
copy1.Dispose();
Assert.Throws<ObjectDisposedException>(() => copy1.Modules[0].Module);
Assert.Throws<ObjectDisposedException>(() => copy1.Modules[1].Module);
Assert.Throws<ObjectDisposedException>(() => copy1.Modules[2].Module);
Assert.Throws<ObjectDisposedException>(() => copy1.GetModules()[0].Module);
Assert.Throws<ObjectDisposedException>(() => copy1.GetModules()[1].Module);
Assert.Throws<ObjectDisposedException>(() => copy1.GetModules()[2].Module);
Assert.NotNull(a.Modules[0].Module);
Assert.NotNull(a.Modules[1].Module);
Assert.NotNull(a.Modules[2].Module);
Assert.NotNull(a.GetModules()[0].Module);
Assert.NotNull(a.GetModules()[1].Module);
Assert.NotNull(a.GetModules()[2].Module);
a.Dispose();
Assert.Throws<ObjectDisposedException>(() => a.Modules[0].Module);
Assert.Throws<ObjectDisposedException>(() => a.Modules[1].Module);
Assert.Throws<ObjectDisposedException>(() => a.Modules[2].Module);
Assert.Throws<ObjectDisposedException>(() => a.GetModules()[0].Module);
Assert.Throws<ObjectDisposedException>(() => a.GetModules()[1].Module);
Assert.Throws<ObjectDisposedException>(() => a.GetModules()[2].Module);
}
[Fact]
public void BadImageFormat()
{
var invalidModuleName = Temp.CreateFile().WriteAllBytes(TestResources.MetadataTests.Invalid.InvalidModuleName);
Assert.Throws<BadImageFormatException>(() => MetadataFileFactory.CreateAssembly(invalidModuleName.Path));
var metadata = MetadataFileFactory.CreateAssembly(invalidModuleName.Path);
Assert.Throws<BadImageFormatException>(() => metadata.GetModules());
}
[Fact, WorkItem(547015, "DevDiv")]
public void IncorrectCustomAssemblyTableSize_TooManyMethodSpecs()
{
Assert.Throws<BadImageFormatException>(() =>
{
AssemblyMetadata.CreateFromImage(TestResources.MetadataTests.Invalid.IncorrectCustomAssemblyTableSize_TooManyMethodSpecs);
});
var metadata = AssemblyMetadata.CreateFromImage(TestResources.MetadataTests.Invalid.IncorrectCustomAssemblyTableSize_TooManyMethodSpecs);
Assert.Throws<BadImageFormatException>(() => metadata.GetModules());
}
}
}
......@@ -338,7 +338,7 @@ public void MetadataImageReferenceFromStream()
r = new MetadataImageReference(new MemoryStream(TestResources.SymbolsTests.General.C1, writable: false));
Assert.Equal("<in-memory assembly>".NeedsLocalization(), r.Display);
Assert.Equal("C, Version=1.0.0.0, Culture=neutral, PublicKeyToken=374d0c2befcd8cc9", ((AssemblyMetadata)r.GetMetadata()).Assembly.Identity.GetDisplayName());
Assert.Equal("C, Version=1.0.0.0, Culture=neutral, PublicKeyToken=374d0c2befcd8cc9", ((AssemblyMetadata)r.GetMetadata()).GetAssembly().Identity.GetDisplayName());
}
}
......
......@@ -22,13 +22,11 @@ public unsafe void CreateFromMetadata_Errors()
Assert.Throws<ArgumentOutOfRangeException>(() => { fixed (byte* ptr = new byte[] { 1, 2, 3 }) ModuleMetadata.CreateFromMetadata((IntPtr)ptr, 0); });
Assert.Throws<ArgumentOutOfRangeException>(() => { fixed (byte* ptr = new byte[] { 1, 2, 3 }) ModuleMetadata.CreateFromMetadata((IntPtr)ptr, -1); });
Assert.Throws<BadImageFormatException>(() =>
fixed (byte* ptr = new byte[] { 1, 2, 3 })
{
fixed (byte* ptr = new byte[] { 1, 2, 3 })
{
ModuleMetadata.CreateFromMetadata((IntPtr)ptr, 3);
}
});
var metadata = ModuleMetadata.CreateFromMetadata((IntPtr)ptr, 3);
Assert.Throws<BadImageFormatException>(() => metadata.GetModuleNames());
}
}
[Fact]
......
......@@ -14,9 +14,9 @@ public void ContainsNoPiaLocalTypes()
metadata1 = AssemblyMetadata.CreateFromImage(TestResources.SymbolsTests.NoPia.LocalTypes1),
metadata2 = AssemblyMetadata.CreateFromImage(TestResources.SymbolsTests.NoPia.LocalTypes2))
{
var pia1 = piaMetadata.Assembly.Modules[0];
var localTypes1 = metadata1.Assembly.Modules[0];
var localTypes2 = metadata2.Assembly.Modules[0];
var pia1 = piaMetadata.GetAssembly().Modules[0];
var localTypes1 = metadata1.GetAssembly().Modules[0];
var localTypes2 = metadata2.GetAssembly().Modules[0];
Assert.False(pia1.ContainsNoPiaLocalTypes());
Assert.False(pia1.ContainsNoPiaLocalTypes());
......
......@@ -198,8 +198,7 @@ internal void AddAnalyzers(ImmutableArray<DiagnosticAnalyzer>.Builder builder, s
analyzerAssembly = GetAssembly();
}
catch (Exception e) if (e is FileLoadException || e is FileNotFoundException || e is BadImageFormatException ||
e is SecurityException || e is ArgumentException || e is PathTooLongException)
catch (Exception e) if (e is IOException || e is BadImageFormatException || e is SecurityException || e is ArgumentException)
{
this.AnalyzerLoadFailed?.Invoke(this, new AnalyzerLoadFailureEventArgs(AnalyzerLoadFailureEventArgs.FailureErrorCode.UnableToLoadAnalyzer, e, null));
return;
......@@ -285,11 +284,13 @@ private IEnumerable<DiagnosticAnalyzer> GetAnalyzersForTypeNames(Assembly analyz
/// <summary>
/// Opens the analyzer dll with the metadata reader and builds a map of language -> analyzer type names.
/// </summary>
/// <exception cref="BadImageFormatException">The PE image format is invalid.</exception>
/// <exception cref="IOException">IO error reading the metadata.</exception>
private static ImmutableDictionary<string, ImmutableHashSet<string>> GetAnalyzerTypeNameMap(string fullPath)
{
using (var assembly = MetadataFileFactory.CreateAssembly(fullPath))
{
var typeNameMap = from module in assembly.Modules
var typeNameMap = from module in assembly.GetModules()
from typeDefHandle in module.MetadataReader.TypeDefinitions
let typeDef = module.MetadataReader.GetTypeDefinition(typeDefHandle)
let typeName = GetFullyQualifiedTypeName(typeDef, module.Module)
......@@ -330,7 +331,7 @@ private static string GetSupportedLanguage(PEModule peModule, CustomAttributeHan
// Single string parameter
if (argsReader.Length > 4)
{
// check prolog
// check prologue
if (argsReader.ReadByte() == 1 && argsReader.ReadByte() == 0)
{
string languageName;
......
......@@ -7,7 +7,7 @@
namespace Microsoft.CodeAnalysis
{
public static partial class MetadataFileFactory
public static partial class MetadataFileFactory // TODO: split to AssemblyMetadataFactory and ModuleMetadataFactory
{
/// <summary>
/// Finds all modules of an assembly on a specified path and builds an instance of <see cref="AssemblyMetadata"/> that represents them.
......@@ -18,33 +18,15 @@ public static partial class MetadataFileFactory
/// <exception cref="IOException">Error reading file <paramref name="fullPath"/>. See <see cref="Exception.InnerException"/> for details.</exception>
public static AssemblyMetadata CreateAssembly(string fullPath)
{
CompilerPathUtilities.RequireAbsolutePath(fullPath, "fullPath");
CompilerPathUtilities.RequireAbsolutePath(fullPath, nameof(fullPath));
return new AssemblyMetadata(CreateModulesFromFile(fullPath));
return new AssemblyMetadata(CreateModule(fullPath), moduleName => CreateModuleFromFile(fullPath, moduleName));
}
private static ImmutableArray<ModuleMetadata> CreateModulesFromFile(string fullPath)
/// <exception cref="IOException">Error reading file <paramref name="fullPath"/>. See <see cref="Exception.InnerException"/> for details.</exception>
private static ModuleMetadata CreateModuleFromFile(string fullPath, string moduleName)
{
ArrayBuilder<ModuleMetadata> moduleBuilder = null;
// if the file isn't an assembly manifest module an error will be reported later
ModuleMetadata manifestModule = CreateModule(fullPath);
string assemblyDir = null;
foreach (string moduleName in manifestModule.GetModuleNames())
{
if (moduleBuilder == null)
{
moduleBuilder = ArrayBuilder<ModuleMetadata>.GetInstance();
moduleBuilder.Add(manifestModule);
assemblyDir = Path.GetDirectoryName(fullPath);
}
var module = CreateModule(PathUtilities.CombineAbsoluteAndRelativePaths(assemblyDir, moduleName));
moduleBuilder.Add(module);
}
return (moduleBuilder != null) ? moduleBuilder.ToImmutableAndFree() : ImmutableArray.Create(manifestModule);
return CreateModule(PathUtilities.CombineAbsoluteAndRelativePaths(Path.GetDirectoryName(fullPath), moduleName));
}
}
}
......@@ -57,7 +57,7 @@ private string ResolveAssemblyName(string displayName)
{
foreach (var fileReference in availableReferences)
{
var identity = ((AssemblyMetadata)fileReference.GetMetadata()).Assembly.Identity;
var identity = ((AssemblyMetadata)fileReference.GetMetadata()).GetAssembly().Identity;
if (assemblyIdentityComparer.ReferenceMatchesDefinition(displayName, identity))
{
return fileReference.FilePath;
......
......@@ -18,8 +18,7 @@ public static partial class MetadataFileFactory
/// </remarks>
/// <exception cref="ArgumentNullException"><paramref name="fullPath"/> is null.</exception>
/// <exception cref="ArgumentException"><paramref name="fullPath"/> is not a valid absolute path.</exception>
/// <exception cref="BadImageFormatException">The PE image format is invalid.</exception>
/// <exception cref="IOException">Error reading file <paramref name="fullPath"/>. See <see cref="Exception.InnerException"/> for details.</exception>
/// <exception cref="IOException">Error opening file <paramref name="fullPath"/>. See <see cref="Exception.InnerException"/> for details.</exception>
/// <exception cref="FileNotFoundException">File <paramref name="fullPath"/> not found.</exception>
public static ModuleMetadata CreateModule(string fullPath)
{
......
......@@ -23,7 +23,11 @@ namespace Microsoft.CodeAnalysis
/// </summary>
internal sealed class PEModule : IDisposable
{
// Either we have PEReader or we have pointer and size of the metadata blob:
private readonly PEReader peReaderOpt;
private readonly IntPtr metadataPointerOpt;
private readonly int metadataSizeOpt;
private MetadataReader lazyMetadataReader;
private ImmutableArray<AssemblyIdentity> lazyAssemblyReferences;
......@@ -71,14 +75,16 @@ internal sealed class PEModule : IDisposable
private static readonly AttributeValueExtractor<ObsoleteAttributeData> AttributeObsoleteDataExtractor = CrackObsoleteAttributeData;
private static readonly AttributeValueExtractor<ObsoleteAttributeData> AttributeDeprecatedDataExtractor = CrackDeprecatedAttributeData;
internal PEModule(PEReader peReader, MetadataReader metadataReader)
internal PEModule(PEReader peReader, IntPtr metadataOpt, int metadataSizeOpt)
{
// shall not throw
Debug.Assert((peReader == null) ^ (metadataReader == null));
Debug.Assert((peReader == null) ^ (metadataOpt == IntPtr.Zero && metadataSizeOpt == 0));
Debug.Assert(metadataOpt == IntPtr.Zero || metadataSizeOpt > 0);
this.peReaderOpt = peReader;
this.lazyMetadataReader = metadataReader;
this.metadataPointerOpt = metadataOpt;
this.metadataSizeOpt = metadataSizeOpt;
this.lazyTypeNameCollection = new Lazy<IdentifierCollection>(ComputeTypeNameCollection);
this.lazyNamespaceNameCollection = new Lazy<IdentifierCollection>(ComputeNamespaceNameCollection);
this.hashesOpt = (peReader != null) ? new PEHashProvider(peReader) : null;
......@@ -141,14 +147,24 @@ internal MetadataReader MetadataReader
{
if (lazyMetadataReader == null)
{
// PEModule is either created with metadata reader or PE reader.
Debug.Assert(peReaderOpt != null);
if (!peReaderOpt.HasMetadata)
MetadataReader newReader;
// PEModule is either created with metadata memory block or a PE reader.
if (metadataPointerOpt != IntPtr.Zero)
{
newReader = new MetadataReader(metadataPointerOpt, metadataSizeOpt, MetadataReaderOptions.ApplyWindowsRuntimeProjections, stringInterner: StringTable.AddShared);
}
else
{
throw new BadImageFormatException(CodeAnalysisResources.PEImageDoesntContainManagedMetadata);
Debug.Assert(peReaderOpt != null);
if (!peReaderOpt.HasMetadata)
{
throw new BadImageFormatException(CodeAnalysisResources.PEImageDoesntContainManagedMetadata);
}
newReader = peReaderOpt.GetMetadataReader(MetadataReaderOptions.ApplyWindowsRuntimeProjections, stringInterner: StringTable.AddShared);
}
var newReader = peReaderOpt.GetMetadataReader(MetadataReaderOptions.ApplyWindowsRuntimeProjections, stringInterner: StringTable.AddShared);
Interlocked.CompareExchange(ref lazyMetadataReader, newReader, null);
}
......
......@@ -6,6 +6,8 @@
using System.IO;
using System.Reflection.Metadata;
using System.Reflection.PortableExecutable;
using System.Threading;
using System.Diagnostics;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis
......@@ -15,12 +17,49 @@ namespace Microsoft.CodeAnalysis
/// </summary>
public sealed class AssemblyMetadata : Metadata
{
private sealed class Data
{
public static readonly Data Disposed = new Data();
public readonly ImmutableArray<ModuleMetadata> Modules;
public readonly PEAssembly Assembly;
private Data()
{
}
public Data(ImmutableArray<ModuleMetadata> modules, PEAssembly assembly)
{
Debug.Assert(!modules.IsDefaultOrEmpty && assembly != null);
this.Modules = modules;
this.Assembly = assembly;
}
public bool IsDisposed
{
get { return Assembly == null; }
}
}
/// <summary>
/// Modules comprising this assembly. The first module is the manifest module.
/// Factory that provides the <see cref="ModuleMetadata"/> for additional modules (other than <see cref="initialModules"/>) of the assembly.
/// Shall only throw <see cref="BadImageFormatException"/> or <see cref="IOException"/>.
/// Null of all modules were specified at construction time.
/// </summary>
public ImmutableArray<ModuleMetadata> Modules { get; private set; }
private readonly Func<string, ModuleMetadata> moduleFactoryOpt;
internal PEAssembly Assembly { get; private set; }
/// <summary>
/// Modules the <see cref="AssemblyMetadata"/> was created with, in case they are eagerly allocated.
/// </summary>
private readonly ImmutableArray<ModuleMetadata> initialModules;
// Encapsulates the modules and the corresponding PEAssembly produced by the modules factory.
private Data lazyData;
// The actual array of modules exposed via Modules property.
// The same modules as the ones produced by the factory or their copies.
private ImmutableArray<ModuleMetadata> lazyPublishedModules;
/// <summary>
/// Cached assembly symbols.
......@@ -30,23 +69,33 @@ public sealed class AssemblyMetadata : Metadata
/// </remarks>
internal readonly WeakList<IAssemblySymbol> CachedSymbols = new WeakList<IAssemblySymbol>();
private AssemblyMetadata(AssemblyMetadata metadata)
// creates a copy
private AssemblyMetadata(AssemblyMetadata other)
: base(isImageOwner: false)
{
this.Assembly = metadata.Assembly;
this.CachedSymbols = metadata.CachedSymbols;
this.Modules = metadata.Modules.SelectAsArray(module => module.Copy());
this.CachedSymbols = other.CachedSymbols;
this.lazyData = other.lazyData;
this.moduleFactoryOpt = other.moduleFactoryOpt;
this.initialModules = other.initialModules;
// Leave lazyPublishedModules unset. Published modules will be set and copied as needed.
}
private AssemblyMetadata(ModuleMetadata module)
internal AssemblyMetadata(ImmutableArray<ModuleMetadata> modules)
: base(isImageOwner: true)
{
this.Modules = ImmutableArray.Create(module);
this.Assembly = new PEAssembly(this, ImmutableArray.Create(module.Module));
Debug.Assert(!modules.IsDefaultOrEmpty);
this.initialModules = modules;
}
internal AssemblyMetadata(ImmutableArray<ModuleMetadata> modules)
internal AssemblyMetadata(ModuleMetadata manifestModule, Func<string, ModuleMetadata> moduleFactory)
: base(isImageOwner: true)
{
this.Modules = modules;
this.Assembly = new PEAssembly(this, modules.SelectAsArray(m => m.Module));
Debug.Assert(manifestModule != null);
Debug.Assert(moduleFactory != null);
this.initialModules = ImmutableArray.Create(manifestModule);
this.moduleFactoryOpt = moduleFactory;
}
/// <summary>
......@@ -56,7 +105,6 @@ internal AssemblyMetadata(ImmutableArray<ModuleMetadata> modules)
/// Manifest module image.
/// </param>
/// <exception cref="ArgumentException"><paramref name="peImage"/> has the default value.</exception>
/// <exception cref="BadImageFormatException">The PE image format is invalid.</exception>
public static AssemblyMetadata CreateFromImage(ImmutableArray<byte> peImage)
{
return Create(ModuleMetadata.CreateFromImage(peImage));
......@@ -107,10 +155,10 @@ public static AssemblyMetadata Create(ModuleMetadata module)
{
if (module == null)
{
throw new ArgumentNullException("module");
throw new ArgumentNullException(nameof(module));
}
return new AssemblyMetadata(module);
return new AssemblyMetadata(ImmutableArray.Create(module));
}
/// <summary>
......@@ -126,24 +174,24 @@ public static AssemblyMetadata Create(ImmutableArray<ModuleMetadata> modules)
{
if (modules.IsDefault)
{
throw new ArgumentException("modules");
throw new ArgumentException(nameof(modules));
}
if (modules.Length == 0)
{
throw new ArgumentException(CodeAnalysisResources.AssemblyMustHaveAtLeastOneModule, "modules");
throw new ArgumentException(CodeAnalysisResources.AssemblyMustHaveAtLeastOneModule, nameof(modules));
}
for (int i = 0; i < modules.Length; i++)
{
if (modules[i] == null)
{
throw new ArgumentNullException("modules[" + i + "]");
throw new ArgumentNullException(nameof(modules) + "[" + i + "]");
}
if (!modules[i].IsImageOwner)
{
throw new ArgumentException(CodeAnalysisResources.ModuleCopyCannotBeUsedToCreateAssemblyMetadata, "modules[" + i + "]");
throw new ArgumentException(CodeAnalysisResources.ModuleCopyCannotBeUsedToCreateAssemblyMetadata, nameof(modules) + "[" + i + "]");
}
}
......@@ -197,34 +245,155 @@ protected override Metadata CommonCopy()
return Copy();
}
/// <summary>
/// Modules comprising this assembly. The first module is the manifest module.
/// </summary>
/// <exception cref="BadImageFormatException">The PE image format is invalid.</exception>
/// <exception cref="IOException">IO error reading the metadata. See <see cref="Exception.InnerException"/> for details.</exception>
/// <exception cref="ObjectDisposedException">The object has been disposed.</exception>
public ImmutableArray<ModuleMetadata> GetModules()
{
if (lazyPublishedModules.IsDefault)
{
var data = GetOrCreateData();
var newModules = data.Modules;
if (!IsImageOwner)
{
newModules = newModules.SelectAsArray(module => module.Copy());
}
ImmutableInterlocked.InterlockedInitialize(ref lazyPublishedModules, newModules);
}
if (lazyData == Data.Disposed)
{
throw new ObjectDisposedException(nameof(AssemblyMetadata));
}
return lazyPublishedModules;
}
/// <exception cref="BadImageFormatException">The PE image format is invalid.</exception>
/// <exception cref="IOException">IO error while reading the metadata. See <see cref="Exception.InnerException"/> for details.</exception>
/// <exception cref="ObjectDisposedException">The object has been disposed.</exception>
internal PEAssembly GetAssembly()
{
return GetOrCreateData().Assembly;
}
/// <exception cref="BadImageFormatException">The PE image format is invalid.</exception>
/// <exception cref="IOException">IO error while reading the metadata. See <see cref="Exception.InnerException"/> for details.</exception>
/// <exception cref="ObjectDisposedException">The object has been disposed.</exception>
private Data GetOrCreateData()
{
if (lazyData == null)
{
ImmutableArray<ModuleMetadata> modules = initialModules;
ImmutableArray<ModuleMetadata>.Builder moduleBuilder = null;
bool createdModulesUsed = false;
try
{
if (this.moduleFactoryOpt != null)
{
Debug.Assert(initialModules.Length == 1);
var additionalModuleNames = initialModules[0].GetModuleNames();
if (additionalModuleNames.Length > 0)
{
moduleBuilder = ImmutableArray.CreateBuilder<ModuleMetadata>(1 + additionalModuleNames.Length);
moduleBuilder.Add(initialModules[0]);
foreach (string moduleName in additionalModuleNames)
{
moduleBuilder.Add(moduleFactoryOpt(moduleName));
}
modules = moduleBuilder.ToImmutable();
}
}
var assembly = new PEAssembly(this, modules.SelectAsArray(m => m.Module));
var newData = new Data(modules, assembly);
createdModulesUsed = Interlocked.CompareExchange(ref lazyData, newData, null) == null;
}
finally
{
if (moduleBuilder != null && !createdModulesUsed)
{
// dispose unused modules created above:
for (int i = initialModules.Length; i < moduleBuilder.Count; i++)
{
moduleBuilder[i].Dispose();
}
}
}
}
if (lazyData.IsDisposed)
{
throw new ObjectDisposedException(nameof(AssemblyMetadata));
}
return lazyData;
}
/// <summary>
/// Disposes all modules contained in the assembly.
/// </summary>
public override void Dispose()
{
foreach (var module in Modules)
var previousData = Interlocked.Exchange(ref lazyData, Data.Disposed);
if (previousData == Data.Disposed || !this.IsImageOwner)
{
// already disposed, or not an owner
return;
}
// AssemblyMetadata assumes their ownership of all modules passed to the constructor.
foreach (var module in initialModules)
{
module.Dispose();
}
if (previousData == null)
{
// no additional modules were created yet => nothing to dispose
return;
}
Debug.Assert(initialModules.Length == 1 || initialModules.Length == previousData.Modules.Length);
// dispose additional modules created lazily:
for (int i = initialModules.Length; i < previousData.Modules.Length; i++)
{
previousData.Modules[i].Dispose();
}
}
/// <summary>
/// Checks if the first module has a single row in Assembly table and that all other modules have none.
/// </summary>
/// <exception cref="BadImageFormatException">The PE image format is invalid.</exception>
/// <exception cref="IOException">IO error reading the metadata. See <see cref="Exception.InnerException"/> for details.</exception>
/// <exception cref="ObjectDisposedException">The object has been disposed.</exception>
internal bool IsValidAssembly()
{
if (!ManifestModule.Module.IsManifestModule)
var modules = GetModules();
if (!modules[0].Module.IsManifestModule)
{
return false;
}
for (int i = 1; i < Modules.Length; i++)
for (int i = 1; i < modules.Length; i++)
{
var module = Modules[i].Module;
// Ignore winmd modules since runtime winmd
// modules may be loaded as non-primary modules.
if (!module.IsLinkedModule &&
(module.MetadataReader.MetadataKind != MetadataKind.WindowsMetadata))
// Ignore winmd modules since runtime winmd modules may be loaded as non-primary modules.
var module = modules[i].Module;
if (!module.IsLinkedModule && module.MetadataReader.MetadataKind != MetadataKind.WindowsMetadata)
{
return false;
}
......@@ -233,14 +402,6 @@ internal bool IsValidAssembly()
return true;
}
/// <summary>
/// The manifest module of the assembly.
/// </summary>
public ModuleMetadata ManifestModule
{
get { return Modules[0]; }
}
/// <summary>
/// Returns the metadata kind. <seealso cref="MetadataImageKind"/>
/// </summary>
......@@ -248,10 +409,5 @@ public override MetadataImageKind Kind
{
get { return MetadataImageKind.Assembly; }
}
internal override bool IsImageOwner
{
get { return ManifestModule.IsImageOwner; }
}
}
}
......@@ -10,8 +10,11 @@ namespace Microsoft.CodeAnalysis
/// </summary>
public abstract class Metadata : IDisposable
{
internal Metadata()
internal readonly bool IsImageOwner;
internal Metadata(bool isImageOwner)
{
this.IsImageOwner = isImageOwner;
}
/// <summary>
......@@ -33,8 +36,5 @@ public Metadata Copy()
{
return CommonCopy();
}
// does this instance own the PE image?
internal abstract bool IsImageOwner { get; }
}
}
......@@ -18,29 +18,25 @@ public sealed partial class ModuleMetadata : Metadata
{
private bool isDisposed;
private readonly bool isImageOwner;
private readonly PEModule module;
private ModuleMetadata(PEReader peReader)
: base(isImageOwner: true)
{
this.module = new PEModule(peReader: peReader, metadataReader: null);
this.isImageOwner = true;
this.module = new PEModule(peReader: peReader, metadataOpt: IntPtr.Zero, metadataSizeOpt: 0);
}
private ModuleMetadata(MetadataReader metadataReader)
private ModuleMetadata(IntPtr metadata, int size)
: base(isImageOwner: true)
{
this.module = new PEModule(peReader: null, metadataReader: metadataReader);
this.isImageOwner = true;
this.module = new PEModule(peReader: null, metadataOpt: metadata, metadataSizeOpt: size);
}
// creates a copy
private ModuleMetadata(ModuleMetadata metadata)
: base(isImageOwner: false)
{
this.module = metadata.Module;
// This instance will not be the owner of the
// resources backing the metadata.
this.isImageOwner = false;
}
/// <summary>
......@@ -51,22 +47,19 @@ private ModuleMetadata(ModuleMetadata metadata)
/// <param name="size">The size of the metadata block.</param>
/// <exception cref="ArgumentNullException"><paramref name="metadata"/> is null.</exception>
/// <exception cref="ArgumentOutOfRangeException"><paramref name="size"/> is not positive.</exception>
/// <exception cref="BadImageFormatException"><paramref name="metadata"/> doesn't contain valid metadata.</exception>
/// <exception cref="NotSupportedException"><paramref name="metadata"/> doesn't represent an assembly (manifest module).</exception>
public static ModuleMetadata CreateFromMetadata(IntPtr metadata, int size)
{
if (metadata == IntPtr.Zero)
{
throw new ArgumentNullException("metadata");
throw new ArgumentNullException(nameof(metadata));
}
if (size <= 0)
{
throw new ArgumentOutOfRangeException(CodeAnalysisResources.SizeHasToBePositive, "size");
throw new ArgumentOutOfRangeException(CodeAnalysisResources.SizeHasToBePositive, nameof(size));
}
var reader = new MetadataReader(metadata, size, MetadataReaderOptions.ApplyWindowsRuntimeProjections, stringInterner: StringTable.AddShared);
return new ModuleMetadata(reader);
return new ModuleMetadata(metadata, size);
}
/// <summary>
......@@ -76,17 +69,16 @@ public static ModuleMetadata CreateFromMetadata(IntPtr metadata, int size)
/// <param name="size">The size of the image pointed to by <paramref name="peImage"/>.</param>
/// <exception cref="ArgumentNullException"><paramref name="peImage"/> is null.</exception>
/// <exception cref="ArgumentOutOfRangeException"><paramref name="size"/> is not positive.</exception>
/// <exception cref="BadImageFormatException"><paramref name="peImage"/> is not valid portable executable image containing CLI metadata</exception>
public static ModuleMetadata CreateFromImage(IntPtr peImage, int size)
{
if (peImage == IntPtr.Zero)
{
throw new ArgumentNullException("peImage");
throw new ArgumentNullException(nameof(peImage));
}
if (size <= 0)
{
throw new ArgumentOutOfRangeException(CodeAnalysisResources.SizeHasToBePositive, "size");
throw new ArgumentOutOfRangeException(CodeAnalysisResources.SizeHasToBePositive, nameof(size));
}
return new ModuleMetadata(new PEReader(peImage, size));
......@@ -97,7 +89,6 @@ public static ModuleMetadata CreateFromImage(IntPtr peImage, int size)
/// </summary>
/// <param name="peImage">The portable executable image beginning with the DOS header ("MZ").</param>
/// <exception cref="ArgumentException"><paramref name="peImage"/> is null.</exception>
/// <exception cref="BadImageFormatException"><paramref name="peImage"/> is not valid portable executable image containing CLI metadata</exception>
public static ModuleMetadata CreateFromImage(IEnumerable<byte> peImage)
{
return CreateFromImage(peImage.AsImmutableOrNull());
......@@ -108,12 +99,11 @@ public static ModuleMetadata CreateFromImage(IEnumerable<byte> peImage)
/// </summary>
/// <param name="peImage">Portable executable image beginning with the DOS header ("MZ").</param>
/// <exception cref="ArgumentException"><paramref name="peImage"/> is null.</exception>
/// <exception cref="BadImageFormatException"><paramref name="peImage"/> is not valid portable executable image containing CLI metadata</exception>
public static ModuleMetadata CreateFromImage(ImmutableArray<byte> peImage)
{
if (peImage.IsDefault)
{
throw new ArgumentException("peImage");
throw new ArgumentException(nameof(peImage));
}
return new ModuleMetadata(new PEReader(peImage));
......@@ -127,7 +117,6 @@ public static ModuleMetadata CreateFromImage(ImmutableArray<byte> peImage)
/// False to close the stream upon disposal of the metadata (the responsibility for disposal of the stream is transferred upon entry of the constructor
/// unless the arguments given are invalid).
/// </param>
/// <exception cref="BadImageFormatException"><paramref name="peStream"/> is not valid portable executable image containing CLI metadata</exception>
/// <exception cref="ArgumentException">The stream doesn't support seek operations.</exception>
/// <exception cref="ArgumentNullException"><paramref name="peStream"/> is null.</exception>
public static ModuleMetadata CreateFromImageStream(Stream peStream, bool leaveOpen = false)
......@@ -144,20 +133,25 @@ public static ModuleMetadata CreateFromImageStream(Stream peStream, bool leaveOp
/// Unless <see cref="PEStreamOptions.LeaveOpen"/> is specified, the responsibility for disposal of the stream is transferred upon entry of the constructor
/// unless the arguments given are invalid.
/// </param>
/// <exception cref="BadImageFormatException"><paramref name="peStream"/> is not valid portable executable image containing CLI metadata</exception>
/// <exception cref="ArgumentException">The stream doesn't support read and seek operations.</exception>
/// <exception cref="ArgumentNullException"><paramref name="peStream"/> is null.</exception>
/// <exception cref="ArgumentOutOfRangeException"><paramref name="options"/> has an invalid value.</exception>
/// <exception cref="BadImageFormatException">
/// <see cref="PEStreamOptions.PrefetchMetadata"/> or <see cref="PEStreamOptions.PrefetchEntireImage"/> is specified and the PE headers of the image are invalid.
/// </exception>
/// <exception cref="IOException">
/// <see cref="PEStreamOptions.PrefetchMetadata"/> or <see cref="PEStreamOptions.PrefetchEntireImage"/> is specified and an error occurs while reading the stream.
/// </exception>
public static ModuleMetadata CreateFromImageStream(Stream peStream, PEStreamOptions options)
{
if (peStream == null)
{
throw new ArgumentNullException("peStream");
throw new ArgumentNullException(nameof(peStream));
}
if (!peStream.CanRead || !peStream.CanSeek)
{
throw new ArgumentException(CodeAnalysisResources.StreamMustSupportReadAndSeek, "peImage");
throw new ArgumentException(CodeAnalysisResources.StreamMustSupportReadAndSeek, nameof(peStream));
}
// ownership of the stream is passed on PEReader:
......@@ -208,7 +202,7 @@ internal PEModule Module
{
if (IsDisposed)
{
throw new ObjectDisposedException(GetType().Name);
throw new ObjectDisposedException(nameof(ModuleMetadata));
}
return module;
......@@ -218,6 +212,7 @@ internal PEModule Module
/// <summary>
/// Name of the module.
/// </summary>
/// <exception cref="BadImageFormatException">Invalid metadata.</exception>
/// <exception cref="ObjectDisposedException">Module has been disposed.</exception>
public string Name
{
......@@ -252,14 +247,14 @@ public ImmutableArray<string> GetModuleNames()
return Module.GetMetadataModuleNamesOrThrow();
}
/// <summary>
/// Returns the metadata reader.
/// </summary>
/// <exception cref="ObjectDisposedException">Module has been disposed.</exception>
/// <exception cref="BadImageFormatException">When an invalid module name is encountered.</exception>
internal MetadataReader MetadataReader
{
get { return Module.MetadataReader; }
}
internal override bool IsImageOwner
{
get { return isImageOwner; }
}
}
}
......@@ -258,7 +258,7 @@ public ReferencedAssemblyIdentity(AssemblyIdentity identity, MetadataReference m
if (assemblyMetadata.IsValidAssembly())
{
PEAssembly assembly = assemblyMetadata.Assembly;
PEAssembly assembly = assemblyMetadata.GetAssembly();
existingReference = TryAddAssembly(
assembly.Identity,
peReference,
......
......@@ -79,33 +79,28 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
' CommonReferenceManager<TCompilation, TAssemblySymbol>.IndexOfCorLibrary
' should be equivalent.
If Not refProps.EmbedInteropTypes AndAlso refProps.Kind = MetadataImageKind.Assembly Then
Dim metadata As Metadata
Try
metadata = DirectCast(reference, PortableExecutableReference).GetMetadata()
Catch
' Failed to get metadata, there will be some errors reported later.
Return True
End Try
If metadata Is Nothing Then
' Failed to get metadata, there will be some errors reported later.
Return True
End If
Dim assemblyMetadata = TryCast(DirectCast(reference, PortableExecutableReference).GetMetadata(), AssemblyMetadata)
Dim assemblyMetadata = DirectCast(metadata, AssemblyMetadata)
If assemblyMetadata Is Nothing OrElse Not assemblyMetadata.IsValidAssembly() Then
' There will be some errors reported later.
Return True
End If
If Not assemblyMetadata.IsValidAssembly Then
' There will be some errors reported later.
Return True
End If
Dim assembly As PEAssembly = assemblyMetadata.GetAssembly()
Dim assembly As PEAssembly = assemblyMetadata.Assembly
If assembly.AssemblyReferences.Length = 0 AndAlso Not assembly.ContainsNoPiaLocalTypes AndAlso assembly.DeclaresTheObjectClass Then
' This reference looks like a valid Cor library candidate, bail out.
Return True
End If
If assembly.AssemblyReferences.Length = 0 AndAlso Not assembly.ContainsNoPiaLocalTypes AndAlso assembly.DeclaresTheObjectClass Then
' This reference looks like a valid Cor library candidate, bail out.
Catch e As BadImageFormatException
' error reported later
Return True
End If
Catch e As IOException
' error reported later
Return True
End Try
End If
Next
......
......@@ -1180,7 +1180,7 @@ lVbRuntimePlus:
' Prefer 'System.Runtime.dll' if it does not have any references
If systemRuntimeMetadata.Kind = MetadataImageKind.Assembly Then
Dim assemblyMetadata = DirectCast(systemRuntimeMetadata, AssemblyMetadata)
If assemblyMetadata.ManifestModule.Module.IsLinkedModule AndAlso assemblyMetadata.Assembly.AssemblyReferences.Length = 0 Then
If assemblyMetadata.GetModules()(0).Module.IsLinkedModule AndAlso assemblyMetadata.GetAssembly.AssemblyReferences.Length = 0 Then
Return New CommandLineReference(systemRuntimePath, New MetadataReferenceProperties(MetadataImageKind.Assembly))
End If
End If
......
......@@ -195,7 +195,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
referencedAssembliesByIdentity.Add(symbol.Identity, symbol)
Next
Dim assembly = metadata.Assembly
Dim assembly = metadata.GetAssembly
Dim peReferences = assembly.AssemblyReferences.SelectAsArray(AddressOf MapAssemblyIdentityToResolvedSymbol, referencedAssembliesByIdentity)
Dim assemblySymbol = New PEAssemblySymbol(assembly, DocumentationProvider.Default, isLinked:=False, importOptions:=importOptions)
......
......@@ -1144,7 +1144,7 @@ End Class
End Select
Next
metadata = AssemblyMetadata.CreateFromImage(consoleappCompilation.EmitToArray()).Assembly.ManifestModule
metadata = AssemblyMetadata.CreateFromImage(consoleappCompilation.EmitToArray()).GetAssembly.ManifestModule
metadataReader = metadata.GetMetadataReader()
Assert.Equal(1, metadataReader.GetTableRowCount(TableIndex.ModuleRef))
......
......@@ -3778,7 +3778,7 @@ End Class
Dim compilation0 = CreateCompilationWithMscorlib(source, options:=TestOptions.DebugDll)
Dim compilation1 = CreateCompilationWithMscorlib(source, options:=TestOptions.DebugDll)
Dim moduleMetadata0 = DirectCast(metadata0.GetMetadata(), AssemblyMetadata).Modules(0)
Dim moduleMetadata0 = DirectCast(metadata0.GetMetadata(), AssemblyMetadata).GetModules(0)
Dim method0 = compilation0.GetMember(Of MethodSymbol)("C.F")
Dim generation0 = EmitBaseline.CreateInitialBaseline(
moduleMetadata0,
......
......@@ -216,7 +216,7 @@ End Class
Dim dllImage = CompileAndVerify(c1).EmittedAssemblyData
Using metadata = AssemblyMetadata.CreateFromImage(dllImage)
Dim emitAssemblyRefs As PEAssembly = metadata.Assembly
Dim emitAssemblyRefs As PEAssembly = metadata.GetAssembly
Dim refs = emitAssemblyRefs.Modules(0).ReferencedAssemblies.AsEnumerable().OrderBy(Function(r) r.Name).ToArray()
......@@ -241,7 +241,7 @@ End Class
dllImage = CompileAndVerify(c2).EmittedAssemblyData
Using metadata = AssemblyMetadata.CreateFromImage(dllImage)
Dim emitAssemblyRefs2 As PEAssembly = metadata.Assembly
Dim emitAssemblyRefs2 As PEAssembly = metadata.GetAssembly
Dim refs2 = emitAssemblyRefs2.Modules(0).ReferencedAssemblies.AsEnumerable().OrderBy(Function(r) r.Name).ToArray()
Assert.Equal(2, refs2.Count)
......@@ -279,7 +279,7 @@ End Class
Dim manifestModule = CompileAndVerify(c1).EmittedAssemblyData
Using metadata = AssemblyMetadata.Create(ModuleMetadata.CreateFromImage(manifestModule), netModule1, netModule2)
Dim emitAddModule As PEAssembly = metadata.Assembly
Dim emitAddModule As PEAssembly = metadata.GetAssembly
Assert.Equal(3, emitAddModule.Modules.Length)
......
......@@ -1472,7 +1472,7 @@ End Class
Assert.Equal(comp1.Assembly, moduleSymbol1.ContainingAssembly)
Dim moduleReferences1 = moduleSymbol1.GetReferencedAssemblies()
Assert.Contains(assemblyMd.Assembly.Identity, moduleReferences1.AsEnumerable())
Assert.Contains(assemblyMd.GetAssembly.Identity, moduleReferences1.AsEnumerable())
Dim moduleTypeSymbol1 = comp1.GlobalNamespace.GetMember(Of NamedTypeSymbol)("TypeFromModule")
Assert.Equal(moduleSymbol1, moduleTypeSymbol1.ContainingModule)
......@@ -1612,7 +1612,7 @@ End Class
Dim CopyRefMetaData = refmetadata.Copy
Assert.NotEqual(refmetadata, CopyRefMetaData)
Assert.Equal(refmetadata.Assembly.ToString, CopyRefMetaData.Assembly.ToString)
Assert.Equal(refmetadata.GetAssembly.ToString, CopyRefMetaData.GetAssembly.ToString)
Dim mca1 As Metadata = refa.GetMetadata()
Dim Copymca1 = mca1.Copy()
......
......@@ -108,7 +108,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.UnitTests
Assert.True(String.Equals(MetadataCache.AssembliesFromFiles.Keys.Single().FullPath, mscorlibPath, StringComparison.OrdinalIgnoreCase))
Dim assembly = cachedAssembly.Metadata.GetTarget().Assembly
Dim assembly = cachedAssembly.Metadata.GetTarget().GetAssembly
Assert.NotNull(assembly)
Assert.True(assembly.Identity.Name.Equals("mscorlib"))
......@@ -120,7 +120,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.UnitTests
Dim mscorlibAsm = DirectCast(cachedAssembly.CachedSymbols.First(), PEAssemblySymbol)
Assert.NotNull(mscorlibAsm)
Assert.Same(mscorlibAsm.Assembly, cachedAssembly.Metadata.GetTarget().Assembly)
Assert.Same(mscorlibAsm.Assembly, cachedAssembly.Metadata.GetTarget().GetAssembly)
Assert.True(mscorlibAsm.Identity.Name.Equals("mscorlib"))
Assert.True(mscorlibAsm.Name.Equals("mscorlib"))
Assert.Equal(1, mscorlibAsm.Modules.Length)
......@@ -512,7 +512,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.UnitTests
Assert.Same(mscorlibInfo.CachedSymbols.First(), mscorlibAsm)
Dim MTTestLib1Info = MetadataCache.AssembliesFromFiles(FileKey.Create(MTTestLib1Path))
Dim assembly = MTTestLib1Info.Metadata.GetTarget().Assembly
Dim assembly = MTTestLib1Info.Metadata.GetTarget().GetAssembly
Assert.NotNull(assembly)
Assert.Equal(1, MTTestLib1Info.CachedSymbols.Count)
......@@ -772,7 +772,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.UnitTests
Assert.Equal(0, MetadataCache.ModulesFromFiles.Count)
Dim cachedAssembly = MetadataCache.AssembliesFromFiles(FileKey.Create(multimoduleRef.FilePath))
Dim assembly = cachedAssembly.Metadata.GetTarget().Assembly
Dim assembly = cachedAssembly.Metadata.GetTarget().GetAssembly
Assert.NotNull(assembly)
Assert.True(assembly.Identity.Name.Equals("MultiModule"))
......
......@@ -356,7 +356,7 @@ static internal void RunValidators(CompilationVerifier verifier, EmitOptions emi
{
using (var emittedMetadata = AssemblyMetadata.Create(verifier.GetAllModuleMetadata()))
{
assemblyValidator(emittedMetadata.Assembly, emitOptions);
assemblyValidator(emittedMetadata.GetAssembly(), emitOptions);
}
}
......
......@@ -142,7 +142,7 @@ internal static void EmitReferences(Compilation compilation, List<ModuleData> de
ImmutableArray<byte> bytes = module.Module.PEReaderOpt.GetEntireImage().GetContent();
if (isManifestModule)
{
dependencies.Add(new ModuleData(((AssemblyMetadata)metadata).Assembly.Identity, OutputKind.DynamicallyLinkedLibrary, bytes, pdb: default(ImmutableArray<byte>), inMemoryModule: !(r is MetadataFileReference)));
dependencies.Add(new ModuleData(((AssemblyMetadata)metadata).GetAssembly().Identity, OutputKind.DynamicallyLinkedLibrary, bytes, pdb: default(ImmutableArray<byte>), inMemoryModule: !(r is MetadataFileReference)));
}
else
{
......@@ -161,7 +161,7 @@ internal static void EmitReferences(Compilation compilation, List<ModuleData> de
private static IEnumerable<ModuleMetadata> EnumerateModules(Metadata metadata)
{
return (metadata.Kind == MetadataImageKind.Assembly) ? ((AssemblyMetadata)metadata).Modules.AsEnumerable() : SpecializedCollections.SingletonEnumerable((ModuleMetadata)metadata);
return (metadata.Kind == MetadataImageKind.Assembly) ? ((AssemblyMetadata)metadata).GetModules().AsEnumerable() : SpecializedCollections.SingletonEnumerable((ModuleMetadata)metadata);
}
internal static bool EmitCompilation(
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册