Example #1
0
        private Dictionary <string, List <ImmutableArray <byte> > > BuildInternalsVisibleToMap()
        {
            var ivtMap = new Dictionary <string, List <ImmutableArray <byte> > >(StringComparer.OrdinalIgnoreCase);

            foreach (string attrVal in Modules[0].GetInternalsVisibleToAttributeValues(Handle))
            {
                AssemblyIdentity identity;
                if (AssemblyIdentity.TryParseDisplayName(attrVal, out identity))
                {
                    List <ImmutableArray <byte> > keys;
                    if (ivtMap.TryGetValue(identity.Name, out keys))
                    {
                        keys.Add(identity.PublicKey);
                    }
                    else
                    {
                        keys = new List <ImmutableArray <byte> >();
                        keys.Add(identity.PublicKey);
                        ivtMap[identity.Name] = keys;
                    }
                }
                else
                {
                    // Dev10 C# reports WRN_InvalidAssemblyName and Dev10 VB reports ERR_FriendAssemblyNameInvalid but
                    // we have no way to do that from here.  Since the absence of these diagnostics does not impact the
                    // user experience enough to justify the work required to produce them, we will simply omit them
                    // (DevDiv #15099, #14348).
                }
            }

            return(ivtMap);
        }
Example #2
0
        public Assembly Load(string displayName)
        {
            if (!AssemblyIdentity.TryParseDisplayName(displayName, out var requestedIdentity))
            {
                return(null);
            }

            ImmutableArray <string> candidatePaths;

            lock (_guard)
            {
                // First, check if this loader already loaded the requested assembly:
                if (_loadedAssembliesByIdentity.TryGetValue(requestedIdentity, out var existingAssembly))
                {
                    return(existingAssembly);
                }
                // Second, check if an assembly file of the same simple name was registered with the loader:
                if (!_knownAssemblyPathsBySimpleName.TryGetValue(requestedIdentity.Name, out var pathList))
                {
                    return(null);
                }

                Debug.Assert(pathList.Count > 0);
                candidatePaths = pathList.ToImmutableArray();
            }

            // Multiple assemblies of the same simple name but different identities might have been registered.
            // Load the one that matches the requested identity (if any).
            foreach (var candidatePath in candidatePaths)
            {
                var candidateIdentity = GetOrAddAssemblyIdentity(candidatePath);

                if (requestedIdentity.Equals(candidateIdentity))
                {
                    return(LoadFromPathUncheckedCore(candidatePath, candidateIdentity));
                }
            }

            return(null);
        }
        // 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);
        }
Example #4
0
        internal TypeSymbol GetTypeSymbol(MetadataHelpers.AssemblyQualifiedTypeName fullName, out bool refersToNoPiaLocalType)
        {
            //
            // Section 23.3 (Custom Attributes) of CLI Spec Partition II:
            //
            // If the parameter kind is System.Type, (also, the middle line in above diagram) its value is
            // stored as a SerString (as defined in the previous paragraph), representing its canonical name.
            // The canonical name is its full type name, followed optionally by the assembly where it is defined,
            // its version, culture and public-key-token. If the assembly name is omitted, the CLI looks first
            // in the current assembly, and then in the system library (mscorlib); in these two special cases,
            // it is permitted to omit the assembly-name, version, culture and public-key-token.

            int referencedAssemblyIndex;

            if (fullName.AssemblyName != null)
            {
                AssemblyIdentity identity;
                if (!AssemblyIdentity.TryParseDisplayName(fullName.AssemblyName, out identity))
                {
                    refersToNoPiaLocalType = false;
                    return(GetUnsupportedMetadataTypeSymbol());
                }

                // the assembly name has to be a full name:
                referencedAssemblyIndex = GetIndexOfReferencedAssembly(identity);
                if (referencedAssemblyIndex == -1)
                {
                    // In rare cases (e.g. assemblies emitted by Reflection.Emit) the identity
                    // might be the identity of the containing assembly. The metadata spec doesn't disallow this.
                    if (!this.IsContainingAssembly(identity))
                    {
                        refersToNoPiaLocalType = false;
                        return(GetUnsupportedMetadataTypeSymbol());
                    }
                }
            }
            else
            {
                // Use this assembly
                referencedAssemblyIndex = -1;
            }

            // Find the top level type
            Debug.Assert(MetadataHelpers.IsValidMetadataIdentifier(fullName.TopLevelType));
            var        mdName    = MetadataTypeName.FromFullName(fullName.TopLevelType);
            TypeSymbol container = LookupTopLevelTypeDefSymbol(ref mdName, referencedAssemblyIndex, out refersToNoPiaLocalType);

            // Process any nested types
            if (fullName.NestedTypes != null)
            {
                if (refersToNoPiaLocalType)
                {
                    // Types nested into local types are not supported.
                    refersToNoPiaLocalType = false;
                    return(GetUnsupportedMetadataTypeSymbol());
                }

                for (int i = 0; i < fullName.NestedTypes.Length; i++)
                {
                    Debug.Assert(MetadataHelpers.IsValidMetadataIdentifier(fullName.NestedTypes[i]));
                    mdName = MetadataTypeName.FromTypeName(fullName.NestedTypes[i]);
                    // Find nested type in the container
                    container = LookupNestedTypeDefSymbol(container, ref mdName);
                }
            }

            //  Substitute type arguments if any
            if (fullName.TypeArguments != null)
            {
                ImmutableArray <bool> argumentRefersToNoPiaLocalType;
                var typeArguments = ResolveTypeArguments(fullName.TypeArguments, out argumentRefersToNoPiaLocalType);
                container = SubstituteTypeParameters(container, typeArguments, argumentRefersToNoPiaLocalType);

                foreach (bool flag in argumentRefersToNoPiaLocalType)
                {
                    if (flag)
                    {
                        refersToNoPiaLocalType = true;
                        break;
                    }
                }
            }
            else
            {
                container = SubstituteWithUnboundIfGeneric(container);
            }

            for (int i = 0; i < fullName.PointerCount; i++)
            {
                container = MakePointerTypeSymbol(container, ImmutableArray <ModifierInfo <TypeSymbol> > .Empty);
            }

            // Process any array type ranks
            if (fullName.ArrayRanks != null)
            {
                foreach (int rank in fullName.ArrayRanks)
                {
                    Debug.Assert(rank >= 0);
                    container = rank == 0 ?
                                GetSZArrayTypeSymbol(container, default(ImmutableArray <ModifierInfo <TypeSymbol> >)) :
                                GetMDArrayTypeSymbol(rank, container, default(ImmutableArray <ModifierInfo <TypeSymbol> >), ImmutableArray <int> .Empty, default(ImmutableArray <int>));
                }
            }

            return(container);
        }