Ejemplo n.º 1
0
        private AssemblyIdentity Port(AssemblyIdentity identity)
        {
            if (identity.IsRetargetable || !identity.IsStrongName || identity.ContentType != AssemblyContentType.Default)
            {
                return(identity);
            }

            Version newVersion = null;
            ImmutableArray <byte> newPublicKeyToken = default(ImmutableArray <byte>);

            var version = (AssemblyVersion)identity.Version;

            if (version >= new AssemblyVersion(2, 0, 0, 0) && version <= new AssemblyVersion(5, 9, 0, 0))
            {
                if (identity.PublicKeyToken.SequenceEqual(s_SILVERLIGHT_PLATFORM_PUBLICKEY_STR_L))
                {
                    if (!policy.SuppressSilverlightPlatformAssembliesPortability)
                    {
                        if (SimpleNameComparer.Equals(identity.Name, "System") ||
                            SimpleNameComparer.Equals(identity.Name, "System.Core"))
                        {
                            newVersion        = (Version)s_VER_ASSEMBLYVERSION_STR_L;
                            newPublicKeyToken = s_ECMA_PUBLICKEY_STR_L;
                        }
                    }
                }
                else if (identity.PublicKeyToken.SequenceEqual(s_SILVERLIGHT_PUBLICKEY_STR_L))
                {
                    if (!policy.SuppressSilverlightLibraryAssembliesPortability)
                    {
                        if (SimpleNameComparer.Equals(identity.Name, "Microsoft.VisualBasic"))
                        {
                            newVersion        = new Version(10, 0, 0, 0);
                            newPublicKeyToken = s_MICROSOFT_PUBLICKEY_STR_L;
                        }

                        if (SimpleNameComparer.Equals(identity.Name, "System.ComponentModel.Composition"))
                        {
                            newVersion        = (Version)s_VER_ASSEMBLYVERSION_STR_L;
                            newPublicKeyToken = s_ECMA_PUBLICKEY_STR_L;
                        }
                    }
                }
            }

            if (newVersion == null)
            {
                return(identity);
            }

            return(new AssemblyIdentity(
                       identity.Name,
                       newVersion,
                       identity.CultureName,
                       newPublicKeyToken,
                       hasPublicKey: false,
                       isRetargetable: identity.IsRetargetable,
                       contentType: AssemblyContentType.Default));
        }
Ejemplo n.º 2
0
 public override int GetHashCode()
 {
     return(SimpleNameComparer.GetHashCode(Name) ^ PublicKeyToken[0]);
 }
Ejemplo n.º 3
0
 public bool Equals(Key other)
 {
     return(SimpleNameComparer.Equals(this.Name, other.Name) &&
            this.PublicKeyToken.SequenceEqual(other.PublicKeyToken));
 }
Ejemplo n.º 4
0
        internal override bool ApplyUnificationPolicies(
            ref AssemblyIdentity reference,
            ref AssemblyIdentity definition,
            AssemblyIdentityParts referenceParts,
            out bool isFxAssembly)
        {
            if (reference.ContentType == AssemblyContentType.Default &&
                SimpleNameComparer.Equals(reference.Name, definition.Name) &&
                SimpleNameComparer.Equals(reference.Name, "mscorlib"))
            {
                isFxAssembly = true;
                reference    = definition;
                return(true);
            }

            if (!reference.IsRetargetable && definition.IsRetargetable)
            {
                // Reference is not retargetable, but definition is retargetable.
                // Non-equivalent.
                isFxAssembly = false;
                return(false);
            }

            // Notes:
            // an assembly might be both retargetable and portable
            // in that case retargeatable table acts as an override.

            // Apply portability policy transforms first (e.g. rewrites references to SL assemblies to their desktop equivalents)
            // If the reference is partial and is missing version or PKT it is not ported.
            reference  = Port(reference);
            definition = Port(definition);

            if (reference.IsRetargetable && !definition.IsRetargetable)
            {
                if (!AssemblyIdentity.IsFullName(referenceParts))
                {
                    isFxAssembly = false;
                    return(false);
                }

                // Reference needs to be retargeted before comparison,
                // unless it's optionally retargetable and we already match the PK
                bool skipRetargeting = IsOptionallyRetargetableAssembly(reference) &&
                                       AssemblyIdentity.KeysEqual(reference, definition);

                if (!skipRetargeting)
                {
                    reference = Retarget(reference);
                }
            }

            // At this point we are in one of the following states:
            //
            //   1) Both ref/def are not retargetable
            //   2) Both ref/def are retargetable
            //   3) Ref is retargetable (and has been retargeted)
            //
            // We can do a straight compare of ref/def at this point using the
            // regular rules

            if (reference.IsRetargetable && definition.IsRetargetable)
            {
                isFxAssembly = IsRetargetableAssembly(definition);
            }
            else
            {
                isFxAssembly = IsFrameworkAssembly(definition);
            }

            return(true);
        }
Ejemplo n.º 5
0
        // internal for testing
        internal ComparisonResult Compare(AssemblyIdentity reference, string referenceDisplayName, AssemblyIdentity definition, out bool unificationApplied, bool ignoreVersion)
        {
            Debug.Assert((reference != null) ^ (referenceDisplayName != null));
            unificationApplied = false;
            AssemblyIdentityParts parts;

            if (reference != null)
            {
                // fast path
                bool?eq = TriviallyEquivalent(reference, definition);
                if (eq.HasValue)
                {
                    return(eq.Value ? ComparisonResult.Equivalent : ComparisonResult.NotEquivalent);
                }

                parts = AssemblyIdentityParts.Name | AssemblyIdentityParts.Version | AssemblyIdentityParts.Culture | AssemblyIdentityParts.PublicKeyToken;
            }
            else
            {
                if (!AssemblyIdentity.TryParseDisplayName(referenceDisplayName, out reference, out parts) ||
                    reference.ContentType != definition.ContentType)
                {
                    return(ComparisonResult.NotEquivalent);
                }
            }

            Debug.Assert(reference.ContentType == definition.ContentType);

            bool isFxAssembly;

            if (!ApplyUnificationPolicies(ref reference, ref definition, parts, out isFxAssembly))
            {
                return(ComparisonResult.NotEquivalent);
            }

            if (ReferenceEquals(reference, definition))
            {
                return(ComparisonResult.Equivalent);
            }

            bool compareCulture        = (parts & AssemblyIdentityParts.Culture) != 0;
            bool comparePublicKeyToken = (parts & AssemblyIdentityParts.PublicKeyOrToken) != 0;

            if (!definition.IsStrongName)
            {
                if (reference.IsStrongName)
                {
                    return(ComparisonResult.NotEquivalent);
                }

                if (!AssemblyIdentity.IsFullName(parts))
                {
                    if (!SimpleNameComparer.Equals(reference.Name, definition.Name))
                    {
                        return(ComparisonResult.NotEquivalent);
                    }

                    if (compareCulture && !CultureComparer.Equals(reference.CultureName, definition.CultureName))
                    {
                        return(ComparisonResult.NotEquivalent);
                    }

                    // version is ignored

                    return(ComparisonResult.Equivalent);
                }

                isFxAssembly = false;
            }

            if (!SimpleNameComparer.Equals(reference.Name, definition.Name))
            {
                return(ComparisonResult.NotEquivalent);
            }

            if (compareCulture && !CultureComparer.Equals(reference.CultureName, definition.CultureName))
            {
                return(ComparisonResult.NotEquivalent);
            }

            if (comparePublicKeyToken && !AssemblyIdentity.KeysEqual(reference, definition))
            {
                return(ComparisonResult.NotEquivalent);
            }

            bool hasSomeVersionParts = (parts & AssemblyIdentityParts.Version) != 0;
            bool hasPartialVersion   = (parts & AssemblyIdentityParts.Version) != AssemblyIdentityParts.Version;

            // If any version parts were specified then compare the versions. The comparison fails if some version parts are missing.
            if (definition.IsStrongName &&
                hasSomeVersionParts &&
                (hasPartialVersion || reference.Version != definition.Version))
            {
                if (isFxAssembly)
                {
                    unificationApplied = true;
                    return(ComparisonResult.Equivalent);
                }

                if (ignoreVersion)
                {
                    return(ComparisonResult.EquivalentIgnoringVersion);
                }

                return(ComparisonResult.NotEquivalent);
            }

            return(ComparisonResult.Equivalent);
        }
Ejemplo n.º 6
0
        // internal for testing
        internal ComparisonResult Compare(AssemblyIdentity reference, string referenceDisplayName, AssemblyIdentity definition, out bool unificationApplied, bool ignoreVersion)
        {
            Debug.Assert((reference != null) ^ (referenceDisplayName != null));
            unificationApplied = false;
            AssemblyIdentityParts parts;

            if (reference != null)
            {
                // fast path
                bool?eq = TriviallyEquivalent(reference, definition);
                if (eq.HasValue)
                {
                    return(eq.Value ? ComparisonResult.Equivalent : ComparisonResult.NotEquivalent);
                }

                parts = AssemblyIdentityParts.Name | AssemblyIdentityParts.Version | AssemblyIdentityParts.Culture | AssemblyIdentityParts.PublicKeyToken;
            }
            else
            {
                if (!AssemblyIdentity.TryParseDisplayName(referenceDisplayName, out reference, out parts) ||
                    reference.ContentType != definition.ContentType)
                {
                    return(ComparisonResult.NotEquivalent);
                }
            }

            Debug.Assert(reference.ContentType == definition.ContentType);

            bool isDefinitionFxAssembly;

            if (!ApplyUnificationPolicies(ref reference, ref definition, parts, out isDefinitionFxAssembly))
            {
                return(ComparisonResult.NotEquivalent);
            }

            if (ReferenceEquals(reference, definition))
            {
                return(ComparisonResult.Equivalent);
            }

            bool compareCulture        = (parts & AssemblyIdentityParts.Culture) != 0;
            bool comparePublicKeyToken = (parts & AssemblyIdentityParts.PublicKeyOrToken) != 0;

            if (!definition.IsStrongName)
            {
                if (reference.IsStrongName)
                {
                    return(ComparisonResult.NotEquivalent);
                }

                if (!AssemblyIdentity.IsFullName(parts))
                {
                    if (!SimpleNameComparer.Equals(reference.Name, definition.Name))
                    {
                        return(ComparisonResult.NotEquivalent);
                    }

                    if (compareCulture && !CultureComparer.Equals(reference.CultureName, definition.CultureName))
                    {
                        return(ComparisonResult.NotEquivalent);
                    }

                    // version is ignored

                    return(ComparisonResult.Equivalent);
                }

                isDefinitionFxAssembly = false;
            }

            if (!SimpleNameComparer.Equals(reference.Name, definition.Name))
            {
                return(ComparisonResult.NotEquivalent);
            }

            if (compareCulture && !CultureComparer.Equals(reference.CultureName, definition.CultureName))
            {
                return(ComparisonResult.NotEquivalent);
            }

            if (comparePublicKeyToken && !AssemblyIdentity.KeysEqual(reference, definition))
            {
                return(ComparisonResult.NotEquivalent);
            }

            bool hasSomeVersionParts = (parts & AssemblyIdentityParts.Version) != 0;
            bool hasPartialVersion   = (parts & AssemblyIdentityParts.Version) != AssemblyIdentityParts.Version;

            // If any version parts were specified then compare the versions. The comparison fails if some version parts are missing.
            if (definition.IsStrongName &&
                hasSomeVersionParts &&
                (hasPartialVersion || reference.Version != definition.Version))
            {
                // Note:
                // System.Numerics.Vectors, Version=4.0 is an FX assembly
                // System.Numerics.Vectors, Version=4.1+ is not an FX assembly
                //
                // It seems like a bug in Fusion: it only determines whether the definition is an FX assembly
                // and calculates the result based upon that, regardless of whether the reference is an FX assembly or not.
                // We do replicate the behavior.
                //
                // As a result unification is asymmetric when comparing the above identities.
                if (isDefinitionFxAssembly)
                {
                    unificationApplied = true;
                    return(ComparisonResult.Equivalent);
                }

                if (ignoreVersion)
                {
                    return(ComparisonResult.EquivalentIgnoringVersion);
                }

                return(ComparisonResult.NotEquivalent);
            }

            return(ComparisonResult.Equivalent);
        }