// Returns null if an assembly of an equivalent identity has not been added previously, otherwise returns the reference that added it. // - Both assembly names are strong (have keys) and are either equal or FX unified // - Both assembly names are weak (no keys) and have the same simple name. private MetadataReference TryAddAssembly(AssemblyIdentity identity, MetadataReference boundReference, DiagnosticBag diagnostics, CommonLocation location, ref Dictionary <string, List <ReferencedAssemblyIdentity> > referencesBySimpleName) { if (referencesBySimpleName == null) { referencesBySimpleName = new Dictionary <string, List <ReferencedAssemblyIdentity> >(StringComparer.OrdinalIgnoreCase); } List <ReferencedAssemblyIdentity> sameSimpleNameIdentities; string simpleName = identity.Name; if (!referencesBySimpleName.TryGetValue(simpleName, out sameSimpleNameIdentities)) { referencesBySimpleName.Add(simpleName, new List <ReferencedAssemblyIdentity> { new ReferencedAssemblyIdentity(identity, boundReference) }); return(null); } ReferencedAssemblyIdentity equivalent = default(ReferencedAssemblyIdentity); if (identity.IsStrongName) { foreach (var other in sameSimpleNameIdentities) { // only compare strong with strong (weak is never equivalent to strong and vice versa) if (other.Identity.IsStrongName && identity.IsEquivalent(other.Identity)) { equivalent = other; break; } } } else { foreach (var other in sameSimpleNameIdentities) { // only compare weak with weak if (!other.Identity.IsStrongName && WeakIdentityPropertiesEquivalent(identity, other.Identity)) { equivalent = other; break; } } } if (equivalent.Identity == null) { sameSimpleNameIdentities.Add(new ReferencedAssemblyIdentity(identity, boundReference)); return(null); } // equivalent found - ignore and/or report an error: if (identity.IsStrongName) { Debug.Assert(equivalent.Identity.IsStrongName); // versions migth have been unified for a Framework assembly: if (identity != equivalent.Identity) { // Dev11 C# reports an error // Dev11 VB keeps both references in the compilation and reports an ambiguity error when a symbol is used. // BREAKING CHANGE in VB: we report an error for both languages // Multiple assemblies with equivalent identity have been imported: '{0}' and '{1}'. Remove one of the duplicate references. MessageProvider.ReportDuplicateMetadataReferenceStrong(diagnostics, location, boundReference, identity, equivalent.MetadataReference, equivalent.Identity); } // If the versions match exactly we ignore duplicates w/o reporting errors while // Dev11 C# reports: // error CS1703: An assembly with the same identity '{0}' has already been imported. Try removing one of the duplicate references. // Dev11 VB reports: // Fatal error BC2000 : compiler initialization failed unexpectedly: Project already has a reference to assembly System. // A second reference to 'D:\Temp\System.dll' cannot be added. } else { MessageProvider.ReportDuplicateMetadataReferenceWeak(diagnostics, location, boundReference, identity, equivalent.MetadataReference, equivalent.Identity); } Debug.Assert(equivalent.MetadataReference != null); return(equivalent.MetadataReference); }