internal MetadataShadowCopy(ShadowCopy primaryModule, ShadowCopy documentationFile, Metadata metadataCopy) { Debug.Assert(primaryModule != null); Debug.Assert(metadataCopy != null); Debug.Assert(!metadataCopy.IsImageOwner); this.primaryModule = primaryModule; this.documentationFile = documentationFile; this.metadataCopy = metadataCopy; }
internal MetadataShadowCopy(ShadowCopy primaryModule, ShadowCopy documentationFile, Metadata metadataCopy) { Debug.Assert(primaryModule != null); Debug.Assert(metadataCopy != null); ////Debug.Assert(!metadataCopy.IsImageOwner); property is now internal _primaryModule = primaryModule; _documentationFile = documentationFile; _metadataCopy = metadataCopy; }
private static IEnumerable<ModuleMetadata> EnumerateModules(Metadata metadata) { return (metadata.Kind == MetadataImageKind.Assembly) ? ((AssemblyMetadata)metadata).GetModules().AsEnumerable() : SpecializedCollections.SingletonEnumerable((ModuleMetadata)metadata); }
internal MetadataImageReference(Metadata metadata, MetadataReferenceProperties properties, DocumentationProvider documentation, string filePath, string display) : base(properties, filePath, documentation ?? DocumentationProvider.Default) { _display = display; _metadata = metadata; }
public TestMetadataReference(Metadata metadata = null, string fullPath = null, string display = null) : base(MetadataReferenceProperties.Assembly, fullPath) { this.metadata = metadata; this.display = display; }
private bool TryGetObservedMetadata(PortableExecutableReference peReference, DiagnosticBag diagnostics, out Metadata metadata) { MetadataOrDiagnostic existing; if (ObservedMetadata.TryGetValue(peReference, out existing)) { Debug.Assert(existing is Metadata || existing is Diagnostic); metadata = existing as Metadata; if (metadata == null) { diagnostics.Add((Diagnostic)existing); } return(true); } metadata = null; return(false); }
/// <summary> /// Resolves given metadata references to assemblies and modules. /// </summary> /// <param name="compilation">The compilation whose references are being resolved.</param> /// <param name="references">List where to store resolved references. References from #r directives will follow references passed to the compilation constructor.</param> /// <param name="boundReferenceDirectiveMap">Maps #r values to successuflly resolved metadata references. Does not contain values that failed to resolve.</param> /// <param name="boundReferenceDirectives">Unique metadata references resolved from #r directives.</param> /// <param name="assemblies">List where to store information about resolved assemblies to.</param> /// <param name="modules">List where to store information about resolved modules to.</param> /// <param name="diagnostics">Diagnostic bag where to report resolution errors.</param> /// <returns> /// Maps index to <paramref name="references"/> to an index of a resolved assembly or module in <paramref name="assemblies"/> or <paramref name="modules"/>, respectively. ///</returns> protected ImmutableArray <ResolvedReference> ResolveMetadataReferences( TCompilation compilation, out ImmutableArray <MetadataReference> references, out IDictionary <string, MetadataReference> boundReferenceDirectiveMap, out ImmutableArray <MetadataReference> boundReferenceDirectives, out ImmutableArray <AssemblyData> assemblies, out ImmutableArray <PEModule> modules, DiagnosticBag diagnostics) { // Locations of all #r directives in the order they are listed in the references list. ImmutableArray <Location> referenceDirectiveLocations; GetCompilationReferences(compilation, diagnostics, out references, out boundReferenceDirectiveMap, out referenceDirectiveLocations); // References originating from #r directives precede references supplied as arguments of the compilation. int referenceCount = references.Length; int referenceDirectiveCount = (referenceDirectiveLocations != null ? referenceDirectiveLocations.Length : 0); int externalReferenceCount = referenceCount - referenceDirectiveCount; var referenceMap = new ResolvedReference[referenceCount]; // Maps references that were added to the reference set (i.e. not filtered out as duplicates) to a set of names that // can be used to alias these references. Duplicate assemblies contribute their aliases into this set. Dictionary <MetadataReference, ArrayBuilder <string> > aliasMap = null; // Used to filter out duplicate references that reference the same file (resolve to the same full normalized path). var boundReferences = new Dictionary <MetadataReference, MetadataReference>(MetadataReferenceEqualityComparer.Instance); // Used to filter out assemblies that have the same strong or weak identity. // Maps simple name to a list of full names. Dictionary <string, List <ReferencedAssemblyIdentity> > assemblyReferencesBySimpleName = null; ArrayBuilder <MetadataReference> uniqueDirectiveReferences = (referenceDirectiveLocations != null) ? ArrayBuilder <MetadataReference> .GetInstance() : null; ArrayBuilder <AssemblyData> assembliesBuilder = null; ArrayBuilder <PEModule> modulesBuilder = null; // When duplicate references with conflicting EmbedInteropTypes flag are encountered, // VB uses the flag from the last one, C# reports an error. We need to enumerate in reverse order // so that we find the one that matters first. for (int referenceIndex = referenceCount - 1; referenceIndex >= 0; referenceIndex--) { var boundReference = references[referenceIndex]; if (boundReference == null) { continue; } // add bound reference if it doesn't exist yet, merging aliases: MetadataReference existingReference; if (boundReferences.TryGetValue(boundReference, out existingReference)) { if (CheckPropertiesConsistency(boundReference, existingReference, diagnostics)) { AddAlias(existingReference, boundReference.Properties.Alias, ref aliasMap); } continue; } boundReferences.Add(boundReference, boundReference); Location location; if (referenceIndex < referenceDirectiveCount) { location = referenceDirectiveLocations[referenceIndex]; uniqueDirectiveReferences.Add(boundReference); } else { location = Location.None; } // compilation reference var compilationReference = boundReference as CompilationReference; if (compilationReference != null) { switch (compilationReference.Properties.Kind) { case MetadataImageKind.Assembly: existingReference = TryAddAssembly( compilationReference.Compilation.Assembly.Identity, boundReference, diagnostics, location, ref assemblyReferencesBySimpleName); if (existingReference != null) { AddAlias(existingReference, boundReference.Properties.Alias, ref aliasMap); continue; } // Note, if SourceAssemblySymbol hasn't been created for // compilationAssembly.Compilation yet, we want this to happen // right now. Conveniently, this constructor will trigger creation of the // SourceAssemblySymbol. var asmData = CreateAssemblyDataForCompilation(compilationReference); AddAssembly(asmData, referenceIndex, referenceMap, ref assembliesBuilder); break; default: throw ExceptionUtilities.UnexpectedValue(compilationReference.Properties.Kind); } continue; } // PE reference var peReference = (PortableExecutableReference)boundReference; Metadata metadata = GetMetadata(peReference, MessageProvider, location, diagnostics); Debug.Assert(metadata != null || diagnostics.HasAnyErrors()); if (metadata != null) { Debug.Assert(metadata != null); switch (peReference.Properties.Kind) { case MetadataImageKind.Assembly: var assemblyMetadata = (AssemblyMetadata)metadata; WeakList <IAssemblySymbol> cachedSymbols = assemblyMetadata.CachedSymbols; if (assemblyMetadata.IsValidAssembly()) { PEAssembly assembly = assemblyMetadata.Assembly; existingReference = TryAddAssembly( assembly.Identity, peReference, diagnostics, location, ref assemblyReferencesBySimpleName); if (existingReference != null) { AddAlias(existingReference, boundReference.Properties.Alias, ref aliasMap); continue; } var asmData = CreateAssemblyDataForFile( assembly, cachedSymbols, peReference.DocumentationProvider, SimpleAssemblyName, compilation.Options.MetadataImportOptions, peReference.Properties.EmbedInteropTypes); AddAssembly(asmData, referenceIndex, referenceMap, ref assembliesBuilder); } else { diagnostics.Add(MessageProvider.CreateDiagnostic(MessageProvider.ERR_MetadataFileNotAssembly, location, peReference.Display)); } // asmData keeps strong ref after this point GC.KeepAlive(assemblyMetadata); break; case MetadataImageKind.Module: var moduleMetadata = (ModuleMetadata)metadata; if (moduleMetadata.Module.IsLinkedModule) { // We don't support netmodules since some checks in the compiler need information from the full PE image // (Machine, Bit32Required, PE image hash). if (!moduleMetadata.Module.IsEntireImageAvailable) { diagnostics.Add(MessageProvider.CreateDiagnostic(MessageProvider.ERR_LinkedNetmoduleMetadataMustProvideFullPEImage, location, peReference.Display)); } AddModule(moduleMetadata.Module, referenceIndex, referenceMap, ref modulesBuilder); } else { diagnostics.Add(MessageProvider.CreateDiagnostic(MessageProvider.ERR_MetadataFileNotModule, location, peReference.Display)); } break; default: throw ExceptionUtilities.UnexpectedValue(peReference.Properties.Kind); } } } if (uniqueDirectiveReferences != null) { uniqueDirectiveReferences.ReverseContents(); boundReferenceDirectives = uniqueDirectiveReferences.ToImmutableAndFree(); } else { boundReferenceDirectives = ImmutableArray <MetadataReference> .Empty; } for (int i = 0; i < referenceMap.Length; i++) { if (!referenceMap[i].IsSkipped) { int count = referenceMap[i].Kind == MetadataImageKind.Assembly ? ((object)assembliesBuilder == null ? 0 : assembliesBuilder.Count) : ((object)modulesBuilder == null ? 0 : modulesBuilder.Count); int reversedIndex = count - 1 - referenceMap[i].Index; referenceMap[i] = new ResolvedReference(reversedIndex, referenceMap[i].Kind, GetAliases(references[i], aliasMap)); } } if (assembliesBuilder == null) { assemblies = ImmutableArray <AssemblyData> .Empty; } else { assembliesBuilder.ReverseContents(); assemblies = assembliesBuilder.ToImmutableAndFree(); } if (modulesBuilder == null) { modules = ImmutableArray <PEModule> .Empty; } else { modulesBuilder.ReverseContents(); modules = modulesBuilder.ToImmutableAndFree(); } return(ImmutableArray.CreateRange(referenceMap)); }