예제 #1
0
            public AssemblyIdentityAndLocation(AssemblyIdentity identity, string location)
            {
                Debug.Assert(identity != null && location != null);

                this.Identity = identity;
                this.Location = location;
            }
예제 #2
0
        private Assembly LoadFromPathUncheckedCore(string fullPath, AssemblyIdentity identity = null)
        {
            Debug.Assert(PathUtilities.IsAbsolute(fullPath));

            // Check if we have already loaded an assembly with the same identity or from the given path.
            Assembly loadedAssembly = null;
            lock (_guard)
            {
                Assembly existingAssembly;
                if (_loadedAssembliesByPath.TryGetValue(fullPath, out existingAssembly))
                {
                    loadedAssembly = existingAssembly;
                }
                else
                {
                    identity = identity ?? GetOrAddAssemblyIdentity(fullPath);
                    if (identity != null && _loadedAssembliesByIdentity.TryGetValue(identity, out existingAssembly))
                    {
                        loadedAssembly = existingAssembly;
                    }
                }
            }

            // Otherwise, load the assembly.
            if (loadedAssembly == null)
            {
                loadedAssembly = LoadFromPathImpl(fullPath);
            }

            // Add the loaded assembly to both path and identity cache.
            return AddToCache(loadedAssembly, fullPath, identity);
        }
예제 #3
0
 public ModuleData(AssemblyIdentity identity, OutputKind kind, ImmutableArray<byte> image, ImmutableArray<byte> pdb, bool inMemoryModule)
 {
     this.Id = new ModuleDataId(identity.Name, identity.GetDisplayName(), GetMvid(image));
     this.Kind = kind;
     this.Image = image;
     this.Pdb = pdb;
     this.InMemoryModule = inMemoryModule;
 }
        public override PortableExecutableReference ResolveMissingAssembly(AssemblyIdentity identity)
        {
            ResolutionAttempts.Add(identity);

            MetadataReference reference;
            string nameAndVersion = identity.Name + (identity.Version != AssemblyIdentity.NullVersion ? $", {identity.Version}" : "");
            return _map.TryGetValue(nameAndVersion, out reference) ? (PortableExecutableReference)reference : null;
        }
        public override PortableExecutableReference ResolveMissingAssembly(MetadataReference definition, AssemblyIdentity referenceIdentity)
        {
            ResolutionAttempts.Add(new ReferenceAndIdentity(definition, referenceIdentity));

            MetadataReference reference;
            string nameAndVersion = referenceIdentity.Name + (referenceIdentity.Version != AssemblyIdentity.NullVersion ? $", {referenceIdentity.Version}" : "");
            return _map.TryGetValue(nameAndVersion, out reference) ? (PortableExecutableReference)reference : null;
        }
예제 #6
0
        public MissingAnalyzerDependency(string analyzerPath, AssemblyIdentity dependencyIdentity)
        {
            Debug.Assert(analyzerPath != null);
            Debug.Assert(dependencyIdentity != null);

            AnalyzerPath = analyzerPath;
            DependencyIdentity = dependencyIdentity;
        }
예제 #7
0
        public AnalyzerDependencyConflict(AssemblyIdentity identity, string analyzerFilePath1, string analyzerFilePath2)
        {
            Debug.Assert(identity != null);
            Debug.Assert(analyzerFilePath1 != null);
            Debug.Assert(analyzerFilePath2 != null);

            Identity = identity;
            AnalyzerFilePath1 = analyzerFilePath1;
            AnalyzerFilePath2 = analyzerFilePath2;
        }
        public override PortableExecutableReference ResolveMissingAssembly(
            MetadataReference definition, AssemblyIdentity referenceIdentity)
        {
            if (resolvedReferences.TryGetValue(referenceIdentity.Name, out var resolvedReference))
            {
                return(resolvedReference);
            }

            resolvedReference = GetPEReference(dependencyResolver.ResolveWithoutReferences(
                                                   new AssemblyName(referenceIdentity.ToString())));
            resolvedReferences = resolvedReferences.Add(referenceIdentity.Name, resolvedReference);
            return(resolvedReference);
        }
        public CodeActionOperation CreateAddMetadataReferenceOperation(ProjectId projectId, AssemblyIdentity assemblyIdentity)
        {
            if (projectId == null)
            {
                throw new ArgumentNullException("projectId");
            }

            if (assemblyIdentity == null)
            {
                throw new ArgumentNullException("assemblyIdentity");
            }

            return new AddMetadataReferenceOperation(projectId, assemblyIdentity);
        }
        public override PortableExecutableReference ResolveMissingAssembly(MetadataReference definition, AssemblyIdentity referenceIdentity)
        {
            // resolve assemblies from the directory containing the test and from directory containing corlib

            string name = referenceIdentity.Name;
            string testDir = Path.GetDirectoryName(GetType().GetTypeInfo().Assembly.ManifestModule.FullyQualifiedName);
            string testDependencyAssemblyPath = Path.Combine(testDir, name + ".dll");
            if (File.Exists(testDependencyAssemblyPath))
            {
                return MetadataReference.CreateFromFile(testDependencyAssemblyPath, s_resolvedMissingAssemblyReferenceProperties);
            }

            string fxDir = Path.GetDirectoryName(typeof(object).GetTypeInfo().Assembly.ManifestModule.FullyQualifiedName);
            string fxAssemblyPath = Path.Combine(fxDir, name + ".dll");
            if (File.Exists(fxAssemblyPath))
            {
                return MetadataReference.CreateFromFile(fxAssemblyPath, s_resolvedMissingAssemblyReferenceProperties);
            }

            return null;
        }
        /// <exception cref="BadImageFormatException"/>
        internal PEAssembly(AssemblyMetadata owner, ImmutableArray<PEModule> modules)
        {
            Debug.Assert(!modules.IsDefault);
            Debug.Assert(modules.Length > 0);

            this.identity = modules[0].ReadAssemblyIdentityOrThrow();

            var refs = ArrayBuilder<AssemblyIdentity>.GetInstance();
            int[] refCounts = new int[modules.Length];

            for (int i = 0; i < modules.Length; i++)
            {
                ImmutableArray<AssemblyIdentity> refsForModule = modules[i].ReferencedAssemblies;
                refCounts[i] = refsForModule.Length;
                refs.AddRange(refsForModule);
            }

            this.modules = modules;
            this.AssemblyReferences = refs.ToImmutableAndFree();
            this.ModuleReferenceCounts = refCounts.AsImmutableOrNull();
            this.owner = owner;
        }
예제 #12
0
        public void TestMissingMetadataSymbol()
        {
            AssemblyIdentity missingAssemblyId = new AssemblyIdentity("foo");
            AssemblySymbol assem = new MockAssemblySymbol("banana");
            ModuleSymbol module = new MissingModuleSymbol(assem, ordinal: -1);
            NamedTypeSymbol container = new MockNamedTypeSymbol("TestClass", Enumerable.Empty<Symbol>(), TypeKind.Class);

            var mms1 = new MissingMetadataTypeSymbol.TopLevel(new MissingAssemblySymbol(missingAssemblyId).Modules[0], "Elvis", "Lives", 2, true);
            Assert.Equal(2, mms1.Arity);
            Assert.Equal("Elvis", mms1.NamespaceName);
            Assert.Equal("Lives", mms1.Name);
            Assert.Equal("Elvis.Lives<,>[missing]", mms1.ToTestDisplayString());
            Assert.Equal("foo", mms1.ContainingAssembly.Identity.Name);

            var mms2 = new MissingMetadataTypeSymbol.TopLevel(module, "Elvis.Is", "Cool", 0, true);
            Assert.Equal(0, mms2.Arity);
            Assert.Equal("Elvis.Is", mms2.NamespaceName);
            Assert.Equal("Cool", mms2.Name);
            Assert.Equal("Elvis.Is.Cool[missing]", mms2.ToTestDisplayString());
            Assert.Same(assem, mms2.ContainingAssembly);

            // TODO: Add test for 3rd constructor.
        }
 private static bool IsTriviallyNonRetargetable(AssemblyIdentity identity)
 {
     // Short-circuit zero-version/non-neutral culture/weak name, 
     // which will never match retargeted identities.
     return identity.CultureName.Length != 0
         || identity.ContentType != AssemblyContentType.Default
         || !identity.IsStrongName;
 }
 private static bool IsRetargetableAssembly(AssemblyIdentity identity)
 {
     bool retargetable, portable;
     IsRetargetableAssembly(identity, out retargetable, out portable);
     return retargetable;
 }
 public override void ReportDuplicateMetadataReferenceWeak(DiagnosticBag diagnostics, Location location, MetadataReference reference, AssemblyIdentity identity, MetadataReference equivalentReference, AssemblyIdentity equivalentIdentity)
 {
     throw new NotImplementedException();
 }
        /// <summary>
        /// Used to match AssemblyRef with AssemblyDef.
        /// </summary>
        /// <param name="definitions">Array of definition identities to match against.</param>
        /// <param name="reference">Reference identity to resolve.</param>
        /// <param name="assemblyIdentityComparer">Assembly identity comparer.</param>
        /// <param name="okToResolveAgainstCompilationBeingCreated"> Is it Ok to resolve reference against the compilation we are creating?</param>
        /// <returns>
        /// Returns an index the reference is bound.
        /// </returns>
        internal static AssemblyReferenceBinding ResolveReferencedAssembly(
            AssemblyIdentity reference,
            ImmutableArray <AssemblyData> definitions,
            AssemblyIdentityComparer assemblyIdentityComparer,
            bool okToResolveAgainstCompilationBeingCreated)
        {
            // Dev11 C# compiler allows the versions to not match exactly, assuming that a newer library may be used instead of an older version.
            // For a given reference it finds a definition with the lowest version that is higher then or equal to the reference version.
            // If match.Version != reference.Version a warning is reported.

            // definition with the lowest version higher than reference version, unless exact version found
            int minHigherVersionDefinition = -1;
            int maxLowerVersionDefinition  = -1;

            // NB: Start at 1, since we checked 0 above.
            const int definitionOffset = 1;

            for (int i = definitionOffset; i < definitions.Length; i++)
            {
                AssemblyIdentity definition = definitions[i].Identity;

                switch (assemblyIdentityComparer.Compare(reference, definition))
                {
                case AssemblyIdentityComparer.ComparisonResult.NotEquivalent:
                    continue;

                case AssemblyIdentityComparer.ComparisonResult.Equivalent:
                    return(new AssemblyReferenceBinding(reference, i));

                case AssemblyIdentityComparer.ComparisonResult.EquivalentIgnoringVersion:
                    if (reference.Version < definition.Version)
                    {
                        // Refers to an older assembly than we have
                        if (minHigherVersionDefinition == -1 || definition.Version < definitions[minHigherVersionDefinition].Identity.Version)
                        {
                            minHigherVersionDefinition = i;
                        }
                    }
                    else
                    {
                        Debug.Assert(reference.Version > definition.Version);

                        // Refers to a newer assembly than we have
                        if (maxLowerVersionDefinition == -1 || definition.Version > definitions[maxLowerVersionDefinition].Identity.Version)
                        {
                            maxLowerVersionDefinition = i;
                        }
                    }

                    continue;
                }
            }

            // we haven't found definition that matches the reference

            if (minHigherVersionDefinition != -1)
            {
                return(new AssemblyReferenceBinding(reference, minHigherVersionDefinition, versionDifference: +1));
            }

            if (maxLowerVersionDefinition != -1)
            {
                return(new AssemblyReferenceBinding(reference, maxLowerVersionDefinition, versionDifference: -1));
            }

            // Handle cases where Windows.winmd is a runtime substitute for a
            // reference to a compile-time winmd. This is for scenarios such as a
            // debugger EE which constructs a compilation from the modules of
            // the running process where Windows.winmd loaded at runtime is a
            // substitute for a collection of Windows.*.winmd compile-time references.
            if (reference.IsWindowsComponent())
            {
                for (int i = definitionOffset; i < definitions.Length; i++)
                {
                    if (IsWindowsRuntime(definitions[i]))
                    {
                        return(new AssemblyReferenceBinding(reference, i));
                    }
                }
            }

            // As in the native compiler (see IMPORTER::MapAssemblyRefToAid), we compare against the
            // compilation (i.e. source) assembly as a last resort.  We follow the native approach of
            // skipping the public key comparison since we have yet to compute it.
            if (okToResolveAgainstCompilationBeingCreated &&
                AssemblyIdentityComparer.SimpleNameComparer.Equals(reference.Name, definitions[0].Identity.Name))
            {
                Debug.Assert(definitions[0].Identity.PublicKeyToken.IsEmpty);
                return(new AssemblyReferenceBinding(reference, 0));
            }

            return(new AssemblyReferenceBinding(reference));
        }
예제 #17
0
 /// <summary>
 /// Enumerates assemblies in the GAC returning those that match given partial name and
 /// architecture.
 /// </summary>
 /// <param name="partialName">Optional partial name.</param>
 /// <param name="architectureFilter">Optional architecture filter.</param>
 public static IEnumerable <AssemblyIdentity> GetAssemblyIdentities(AssemblyName partialName, Func <ProcessorArchitecture, bool> architectureFilter = null)
 {
     return(GetAssemblyIdentities(AssemblyIdentity.ToAssemblyNameObject(partialName), architectureFilter));
 }
예제 #18
0
            public override Assembly Load(AssemblyIdentity identity, string location = null)
            {
                if (dynamicModule != null && identity.Name == _dynamicAssemblyName.Name)
                {
                    return dynamicModule.Assembly;
                }

                return assemblyLoader.Load(identity, location);
            }
예제 #19
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);
        }
예제 #20
0
 public virtual PortableExecutableReference?ResolveMissingAssembly(MetadataReference definition, AssemblyIdentity referenceIdentity) => null;
예제 #21
0
        /// <summary>
        /// Given that an assembly with identity assemblyGrantingAccessIdentity granted access to assemblyWantingAccess,
        /// check the public keys to ensure the internals-visible-to check should succeed. This is used by both the
        /// C# and VB implementations as a helper to implement `bool IAssemblySymbol.GivesAccessTo(IAssemblySymbol toAssembly)`.
        /// </summary>
        internal static IVTConclusion PerformIVTCheck(
            this AssemblyIdentity assemblyGrantingAccessIdentity,
            ImmutableArray <byte> assemblyWantingAccessKey,
            ImmutableArray <byte> grantedToPublicKey)
        {
            // This gets a bit complicated. Let's break it down.
            //
            // First off, let's assume that the "other" assembly is GrantingAssembly.DLL, that the "this"
            // assembly is "WantingAssembly.DLL", and that GrantingAssembly has named WantingAssembly as a friend (that is a precondition
            // to calling this method). Whether we allow WantingAssembly to see internals of GrantingAssembly depends on these four factors:
            //
            // q1) Is GrantingAssembly strong-named?
            // q2) Did GrantingAssembly name WantingAssembly as a friend via a strong name?
            // q3) Is WantingAssembly strong-named?
            // q4) Does GrantingAssembly give a strong-name for WantingAssembly that matches our strong name?
            //
            // Before we dive into the details, we should mention two additional facts:
            //
            // * If the answer to q1 is "yes", and GrantingAssembly was compiled by a Roslyn compiler, then q2 must be "yes" also.
            //   Strong-named GrantingAssembly must only be friends with strong-named WantingAssembly. See the blog article
            //   http://blogs.msdn.com/b/ericlippert/archive/2009/06/04/alas-smith-and-jones.aspx
            //   for an explanation of why this feature is desirable.
            //
            //   Now, just because the compiler enforces this rule does not mean that we will never run into
            //   a scenario where GrantingAssembly is strong-named and names WantingAssembly via a weak name. Not all assemblies
            //   were compiled with a Roslyn compiler. We still need to deal sensibly with this situation.
            //   We do so by ignoring the problem; if strong-named GrantingAssembly extends friendship to weak-named
            //   WantingAssembly then we're done; any assembly named WantingAssembly is a friend of GrantingAssembly.
            //
            //   Incidentally, the C# compiler produces error CS1726, ERR_FriendAssemblySNReq, and VB produces
            //   the error VB31535, ERR_FriendAssemblyStrongNameRequired, when compiling
            //   a strong-named GrantingAssembly that names a weak-named WantingAssembly as its friend.
            //
            // * If the answer to q1 is "no" and the answer to q3 is "yes" then we are in a situation where
            //   strong-named WantingAssembly is referencing weak-named GrantingAssembly, which is illegal. In the dev10 compiler
            //   we do not give an error about this until emit time. In Roslyn we have a new error, CS7029,
            //   which we give before emit time when we detect that weak-named GrantingAssembly has given friend access
            //   to strong-named WantingAssembly, which then references GrantingAssembly. However, we still want to give friend
            //   access to WantingAssembly for the purposes of semantic analysis.
            //
            // Roslyn C# does not yet give an error in other circumstances whereby a strong-named assembly
            // references a weak-named assembly. See https://github.com/dotnet/roslyn/issues/26722
            //
            // Let's make a chart that illustrates all the possible answers to these four questions, and
            // what the resulting accessibility should be:
            //
            // case q1  q2  q3  q4  Result                 Explanation
            // 1    YES YES YES YES SUCCESS          GrantingAssembly has named this strong-named WantingAssembly as a friend.
            // 2    YES YES YES NO  NO MATCH         GrantingAssembly has named a different strong-named WantingAssembly as a friend.
            // 3    YES YES NO  NO  NO MATCH         GrantingAssembly has named a strong-named WantingAssembly as a friend, but this WantingAssembly is weak-named.
            // 4    YES NO  YES NO  SUCCESS          GrantingAssembly has improperly (*) named any WantingAssembly as its friend. But we honor its offer of friendship.
            // 5    YES NO  NO  NO  SUCCESS          GrantingAssembly has improperly (*) named any WantingAssembly as its friend. But we honor its offer of friendship.
            // 6    NO  YES YES YES SUCCESS, BAD REF GrantingAssembly has named this strong-named WantingAssembly as a friend, but WantingAssembly should not be referring to a weak-named GrantingAssembly.
            // 7    NO  YES YES NO  NO MATCH         GrantingAssembly has named a different strong-named WantingAssembly as a friend.
            // 8    NO  YES NO  NO  NO MATCH         GrantingAssembly has named a strong-named WantingAssembly as a friend, but this WantingAssembly is weak-named.
            // 9    NO  NO  YES NO  SUCCESS, BAD REF GrantingAssembly has named any WantingAssembly as a friend, but WantingAssembly should not be referring to a weak-named GrantingAssembly.
            // 10   NO  NO  NO  NO  SUCCESS          GrantingAssembly has named any WantingAssembly as its friend.
            //
            // (*) GrantingAssembly was not built with a Roslyn compiler, which would have prevented this.
            //
            // This method never returns NoRelationshipClaimed because if control got here, then we assume
            // (as a precondition) that GrantingAssembly named WantingAssembly as a friend somehow.

            bool q1 = assemblyGrantingAccessIdentity.IsStrongName;
            bool q2 = !grantedToPublicKey.IsDefaultOrEmpty;
            bool q3 = !assemblyWantingAccessKey.IsDefaultOrEmpty;
            bool q4 = (q2 & q3) && ByteSequenceComparer.Equals(grantedToPublicKey, assemblyWantingAccessKey);

            // Cases 2, 3, 7 and 8:
            if (q2 && !q4)
            {
                return(IVTConclusion.PublicKeyDoesntMatch);
            }

            // Cases 6 and 9:
            if (!q1 && q3)
            {
                return(IVTConclusion.OneSignedOneNot);
            }

            // Cases 1, 4, 5 and 10:
            return(IVTConclusion.Match);
        }
예제 #22
0
        internal override bool ApplyUnificationPolicies(
            ref AssemblyIdentity reference,
            ref AssemblyIdentity definition,
            AssemblyIdentityParts referenceParts,
            out bool isDefinitionFxAssembly)
        {
            if (reference.ContentType == AssemblyContentType.Default &&
                SimpleNameComparer.Equals(reference.Name, definition.Name) &&
                SimpleNameComparer.Equals(reference.Name, "mscorlib"))
            {
                isDefinitionFxAssembly = true;
                reference = definition;
                return(true);
            }

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

            // Notes:
            // an assembly might be both retargetable and portable
            // in that case retargetable 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))
                {
                    isDefinitionFxAssembly = 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)
            {
                isDefinitionFxAssembly = IsRetargetableAssembly(definition);
            }
            else
            {
                isDefinitionFxAssembly = IsFrameworkAssembly(definition);
            }

            return(true);
        }
예제 #23
0
 private static bool IsRetargetableAssembly(AssemblyIdentity identity)
 {
     IsRetargetableAssembly(identity, out bool retargetable, out bool portable);
     return(retargetable);
 }
예제 #24
0
        /// <summary>
        /// Compares reference assembly identity with definition identity and returns their relationship.
        /// </summary>
        /// <param name="reference">Reference identity.</param>
        /// <param name="definition">Definition identity.</param>
        public ComparisonResult Compare(AssemblyIdentity reference, AssemblyIdentity definition)
        {
            bool unificationApplied;

            return(Compare(reference, null, definition, out unificationApplied, ignoreVersion: true));
        }
예제 #25
0
        /// <summary>
        /// Compares assembly reference identity with definition identity.
        /// </summary>
        /// <param name="reference">Reference assembly identity.</param>
        /// <param name="definition">Full assembly display name.</param>
        /// <returns>True if the reference identity matches the definition identity.</returns>
        public bool ReferenceMatchesDefinition(AssemblyIdentity reference, AssemblyIdentity definition)
        {
            bool unificationApplied;

            return(Compare(reference, null, definition, out unificationApplied, ignoreVersion: false) != ComparisonResult.NotEquivalent);
        }
        private static AssemblyIdentity Retarget(AssemblyIdentity identity)
        {
            if (IsTriviallyNonRetargetable(identity))
            {
                return identity;
            }

            FrameworkRetargetingDictionary.Value value;
            if (g_arRetargetPolicy.TryGetValue(identity, out value))
            {
                return new AssemblyIdentity(
                    value.NewName ?? identity.Name,
                    (Version)value.NewVersion,
                    identity.CultureName,
                    value.NewPublicKeyToken,
                    hasPublicKey: false,
                    isRetargetable: identity.IsRetargetable,
                    contentType: AssemblyContentType.Default);
            }

            return identity;
        }
        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;
        }
예제 #28
0
 protected abstract bool IsContainingAssembly(AssemblyIdentity identity);
예제 #29
0
        private static ModuleBuilder CreateDynamicModule(AssemblyBuilderAccess access, AssemblyIdentity name, string fileName)
        {
            var assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(name.ToAssemblyName(), access);

            if (DisableJitOptimizations)
            {
                assemblyBuilder.SetCustomAttribute(new CustomAttributeBuilder(
                    typeof(DebuggableAttribute).GetConstructor(new[] { typeof(DebuggableAttribute.DebuggingModes) }),
                    new object[] { DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations }));
            }

            const string moduleName = "InteractiveModule";

            if (access == AssemblyBuilderAccess.RunAndSave)
            {
                return assemblyBuilder.DefineDynamicModule(moduleName, fileName, emitSymbolInfo: false);
            }
            else
            {
                return assemblyBuilder.DefineDynamicModule(moduleName, emitSymbolInfo: false);
            }
        }
예제 #30
0
        // Internal for testing.
        internal static IEnumerable <AssemblyIdentity.IAssemblyName> GetAssemblyObjects(
            AssemblyIdentity.IAssemblyName partialNameFilter,
            Func <ProcessorArchitecture, bool> architectureFilter)
        {
            IAssemblyEnum enumerator;

            AssemblyIdentity.IApplicationContext applicationContext = null;

            int hr = CreateAssemblyEnum(out enumerator, applicationContext, partialNameFilter, ASM_CACHE.GAC, IntPtr.Zero);

            if (hr == S_FALSE)
            {
                // no assembly found
                yield break;
            }
            else if (hr != S_OK)
            {
                Exception e = Marshal.GetExceptionForHR(hr);
                if (e is FileNotFoundException)
                {
                    // invalid assembly name:
                    yield break;
                }
                else if (e != null)
                {
                    throw e;
                }
                else
                {
                    // for some reason it might happen that CreateAssemblyEnum returns non-zero HR that doesn't correspond to any exception:
                    throw new ArgumentException(CodeAnalysisResources.InvalidAssemblyName);
                }
            }

            while (true)
            {
                AssemblyIdentity.IAssemblyName nameObject;

                hr = enumerator.GetNextAssembly(out applicationContext, out nameObject, 0);
                if (hr != 0)
                {
                    if (hr < 0)
                    {
                        Marshal.ThrowExceptionForHR(hr);
                    }

                    break;
                }

                if (architectureFilter != null)
                {
                    var assemblyArchitecture = AssemblyIdentity.GetProcessorArchitecture(nameObject);
                    if (!architectureFilter(assemblyArchitecture))
                    {
                        continue;
                    }
                }

                yield return(nameObject);
            }
        }
예제 #31
0
 public override Assembly Load(AssemblyIdentity identity, string location = null)
 {
     return Resolve(identity.Name) ?? _assemblyLoader.Load(identity, location);
 }
 public ReferencedAssemblyIdentity(AssemblyIdentity identity, MetadataReference metadataReference)
 {
     Identity          = identity;
     MetadataReference = metadataReference;
 }
예제 #33
0
        private Assembly AddToCache(Assembly assembly, string fullPath, AssemblyIdentity identity)
        {
            Debug.Assert(PathUtilities.IsAbsolute(fullPath));
            Debug.Assert(assembly != null);

            identity = AddToCache(fullPath, identity ?? AssemblyIdentity.FromAssemblyDefinition(assembly));
            Debug.Assert(identity != null);

            lock (_guard)
            {
                // The same assembly may be loaded from two different full paths (e.g. when loaded from GAC, etc.),
                // or another thread might have loaded the assembly after we checked above.
                Assembly existingAssembly;
                if (_loadedAssembliesByIdentity.TryGetValue(identity, out existingAssembly))
                {
                    assembly = existingAssembly;
                }
                else
                {
                    _loadedAssembliesByIdentity.Add(identity, assembly);
                }

                // An assembly file might be replaced by another file with a different identity.
                // Last one wins.
                _loadedAssembliesByPath[fullPath] = assembly;

                return assembly;
            }
        }
        // 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, Location 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 && IdentityComparer.ReferenceMatchesDefinition(identity, 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)
                {
                    // Dev12 C# reports an error
                    // Dev12 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
                // Dev12 C# reports:
                //   error CS1703: An assembly with the same identity '{0}' has already been imported. Try removing one of the duplicate references.
                // Dev12 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
            {
                Debug.Assert(!equivalent.Identity.IsStrongName);

                // Dev12 reports an error for all weak-named assemblies, even if the versions are the same.
                // We treat assemblies with the same name and version equal even if they don't have a strong name.
                // This change allows us to de-duplicate #r references based on identities rather than full paths,
                // and is closer to platforms that don't support strong names and consider name and version enough
                // to identify an assembly. An identity without version is considered to have version 0.0.0.0.

                if (identity != equivalent.Identity)
                {
                    MessageProvider.ReportDuplicateMetadataReferenceWeak(diagnostics, location, boundReference, identity, equivalent.MetadataReference, equivalent.Identity);
                }
            }

            Debug.Assert(equivalent.MetadataReference != null);
            return(equivalent.MetadataReference);
        }
예제 #35
0
 /// <summary>
 /// Given the identity of an assembly referenced by this module, finds
 /// the index of that assembly in the list of assemblies referenced by
 /// the current module.
 /// </summary>
 protected abstract int GetIndexOfReferencedAssembly(AssemblyIdentity identity);
예제 #36
0
        private AssemblyIdentity Port(AssemblyIdentity identity)
        {
            if (
                identity.IsRetargetable ||
                !identity.IsStrongName ||
                identity.ContentType != AssemblyContentType.Default
                )
            {
                return(identity);
            }

            Version?newVersion = null;
            ImmutableArray <byte> newPublicKeyToken = default;

            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
                       ));
        }
예제 #37
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);
        }
예제 #38
0
        /// <summary>
        /// Returns null if an assembly of an equivalent identity has not been added previously, otherwise returns the reference that added it.
        /// Two identities are considered equivalent if
        /// - 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.
        /// </summary>
        private MetadataReference TryAddAssembly(
            AssemblyIdentity identity,
            MetadataReference reference,
            int assemblyIndex,
            DiagnosticBag diagnostics,
            Location location,
            Dictionary <string, List <ReferencedAssemblyIdentity> > referencesBySimpleName,
            bool supersedeLowerVersions)
        {
            var referencedAssembly = new ReferencedAssemblyIdentity(identity, reference, assemblyIndex);

            List <ReferencedAssemblyIdentity> sameSimpleNameIdentities;

            if (!referencesBySimpleName.TryGetValue(identity.Name, out sameSimpleNameIdentities))
            {
                referencesBySimpleName.Add(identity.Name, new List <ReferencedAssemblyIdentity> {
                    referencedAssembly
                });
                return(null);
            }

            if (supersedeLowerVersions)
            {
                foreach (var other in sameSimpleNameIdentities)
                {
                    if (identity.Version == other.Identity.Version)
                    {
                        return(other.Reference);
                    }
                }

                // Keep all versions of the assembly and the first identity in the list the one with the highest version:
                if (sameSimpleNameIdentities[0].Identity.Version > identity.Version)
                {
                    sameSimpleNameIdentities.Add(referencedAssembly);
                }
                else
                {
                    sameSimpleNameIdentities.Add(sameSimpleNameIdentities[0]);
                    sameSimpleNameIdentities[0] = referencedAssembly;
                }

                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).
                    // In order to eliminate duplicate references we need to try to match their identities in both directions since
                    // ReferenceMatchesDefinition is not necessarily symmetric.
                    // (e.g. System.Numerics.Vectors, Version=4.1+ matches System.Numerics.Vectors, Version=4.0, but not the other way around.)
                    if (other.Identity.IsStrongName &&
                        IdentityComparer.ReferenceMatchesDefinition(identity, other.Identity) &&
                        IdentityComparer.ReferenceMatchesDefinition(other.Identity, 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(referencedAssembly);
                return(null);
            }

            // equivalent found - ignore and/or report an error:

            if (identity.IsStrongName)
            {
                Debug.Assert(equivalent.Identity.IsStrongName);

                // versions might have been unified for a Framework assembly:
                if (identity != equivalent.Identity)
                {
                    // Dev12 C# reports an error
                    // Dev12 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, reference, identity, equivalent.Reference, equivalent.Identity);
                }
                // If the versions match exactly we ignore duplicates w/o reporting errors while
                // Dev12 C# reports:
                //   error CS1703: An assembly with the same identity '{0}' has already been imported. Try removing one of the duplicate references.
                // Dev12 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
            {
                Debug.Assert(!equivalent.Identity.IsStrongName);

                // Dev12 reports an error for all weak-named assemblies, even if the versions are the same.
                // We treat assemblies with the same name and version equal even if they don't have a strong name.
                // This change allows us to de-duplicate #r references based on identities rather than full paths,
                // and is closer to platforms that don't support strong names and consider name and version enough
                // to identify an assembly. An identity without version is considered to have version 0.0.0.0.

                if (identity != equivalent.Identity)
                {
                    MessageProvider.ReportDuplicateMetadataReferenceWeak(diagnostics, location, reference, identity, equivalent.Reference, equivalent.Identity);
                }
            }

            Debug.Assert(equivalent.Reference != null);
            return(equivalent.Reference);
        }
예제 #39
0
 public abstract void ReportDuplicateMetadataReferenceWeak(DiagnosticBag diagnostics, Location location, MetadataReference reference, AssemblyIdentity identity, MetadataReference equivalentReference, AssemblyIdentity equivalentIdentity);
예제 #40
0
        /// <summary>
        /// Used to match AssemblyRef with AssemblyDef.
        /// </summary>
        /// <param name="definitions">Array of definition identities to match against.</param>
        /// <param name="definitionStartIndex">An index of the first definition to consider, <paramref name="definitions"/> preceding this index are ignored.</param>
        /// <param name="reference">Reference identity to resolve.</param>
        /// <param name="assemblyIdentityComparer">Assembly identity comparer.</param>
        /// <returns>
        /// Returns an index the reference is bound.
        /// </returns>
        internal static AssemblyReferenceBinding ResolveReferencedAssembly(
            AssemblyIdentity reference,
            ImmutableArray <AssemblyData> definitions,
            int definitionStartIndex,
            AssemblyIdentityComparer assemblyIdentityComparer)
        {
            // Dev11 C# compiler allows the versions to not match exactly, assuming that a newer library may be used instead of an older version.
            // For a given reference it finds a definition with the lowest version that is higher then or equal to the reference version.
            // If match.Version != reference.Version a warning is reported.

            // definition with the lowest version higher than reference version, unless exact version found
            int minHigherVersionDefinition = -1;
            int maxLowerVersionDefinition  = -1;

            // Skip assembly being built for now; it will be considered at the very end:
            bool resolveAgainstAssemblyBeingBuilt = definitionStartIndex == 0;

            definitionStartIndex = Math.Max(definitionStartIndex, 1);

            for (int i = definitionStartIndex; i < definitions.Length; i++)
            {
                AssemblyIdentity definition = definitions[i].Identity;

                switch (assemblyIdentityComparer.Compare(reference, definition))
                {
                case AssemblyIdentityComparer.ComparisonResult.NotEquivalent:
                    continue;

                case AssemblyIdentityComparer.ComparisonResult.Equivalent:
                    return(new AssemblyReferenceBinding(reference, i));

                case AssemblyIdentityComparer.ComparisonResult.EquivalentIgnoringVersion:
                    if (reference.Version < definition.Version)
                    {
                        // Refers to an older assembly than we have
                        if (minHigherVersionDefinition == -1 || definition.Version < definitions[minHigherVersionDefinition].Identity.Version)
                        {
                            minHigherVersionDefinition = i;
                        }
                    }
                    else
                    {
                        Debug.Assert(reference.Version > definition.Version);

                        // Refers to a newer assembly than we have
                        if (maxLowerVersionDefinition == -1 || definition.Version > definitions[maxLowerVersionDefinition].Identity.Version)
                        {
                            maxLowerVersionDefinition = i;
                        }
                    }

                    continue;

                default:
                    throw ExceptionUtilities.Unreachable;
                }
            }

            // we haven't found definition that matches the reference

            if (minHigherVersionDefinition != -1)
            {
                return(new AssemblyReferenceBinding(reference, minHigherVersionDefinition, versionDifference: +1));
            }

            if (maxLowerVersionDefinition != -1)
            {
                return(new AssemblyReferenceBinding(reference, maxLowerVersionDefinition, versionDifference: -1));
            }

            // Handle cases where Windows.winmd is a runtime substitute for a
            // reference to a compile-time winmd. This is for scenarios such as a
            // debugger EE which constructs a compilation from the modules of
            // the running process where Windows.winmd loaded at runtime is a
            // substitute for a collection of Windows.*.winmd compile-time references.
            if (reference.IsWindowsComponent())
            {
                for (int i = definitionStartIndex; i < definitions.Length; i++)
                {
                    if (definitions[i].Identity.IsWindowsRuntime())
                    {
                        return(new AssemblyReferenceBinding(reference, i));
                    }
                }
            }

            // In the IDE it is possible the reference we're looking for is a
            // compilation reference to a source assembly. However, if the reference
            // is of ContentType WindowsRuntime then the compilation will never
            // match since all C#/VB WindowsRuntime compilations output .winmdobjs,
            // not .winmds, and the ContentType of a .winmdobj is Default.
            // If this is the case, we want to ignore the ContentType mismatch and
            // allow the compilation to match the reference.
            if (reference.ContentType == AssemblyContentType.WindowsRuntime)
            {
                for (int i = definitionStartIndex; i < definitions.Length; i++)
                {
                    var definition        = definitions[i].Identity;
                    var sourceCompilation = definitions[i].SourceCompilation;
                    if (definition.ContentType == AssemblyContentType.Default &&
                        sourceCompilation?.Options.OutputKind == OutputKind.WindowsRuntimeMetadata &&
                        AssemblyIdentityComparer.SimpleNameComparer.Equals(reference.Name, definition.Name) &&
                        reference.Version.Equals(definition.Version) &&
                        reference.IsRetargetable == definition.IsRetargetable &&
                        AssemblyIdentityComparer.CultureComparer.Equals(reference.CultureName, definition.CultureName) &&
                        AssemblyIdentity.KeysEqual(reference, definition))
                    {
                        return(new AssemblyReferenceBinding(reference, i));
                    }
                }
            }

            // As in the native compiler (see IMPORTER::MapAssemblyRefToAid), we compare against the
            // compilation (i.e. source) assembly as a last resort.  We follow the native approach of
            // skipping the public key comparison since we have yet to compute it.
            if (resolveAgainstAssemblyBeingBuilt &&
                AssemblyIdentityComparer.SimpleNameComparer.Equals(reference.Name, definitions[0].Identity.Name))
            {
                Debug.Assert(definitions[0].Identity.PublicKeyToken.IsEmpty);
                return(new AssemblyReferenceBinding(reference, 0));
            }

            return(new AssemblyReferenceBinding(reference));
        }
 public AddMetadataReferenceOperation(ProjectId projectId, AssemblyIdentity assemblyIdentity)
 {
     _projectId = projectId;
     _assemblyIdentity = assemblyIdentity;
 }
 internal virtual bool ApplyUnificationPolicies(ref AssemblyIdentity reference, ref AssemblyIdentity definition, AssemblyIdentityParts referenceParts, out bool isDefinitionFxAssembly)
 {
     isDefinitionFxAssembly = false;
     return(true);
 }
        /// <summary>
        /// Returns true if the identity is a Framework 4.5 or lower assembly.
        /// </summary>
        private static bool IsFrameworkAssembly(AssemblyIdentity identity)
        {
            // Note:
            // FrameworkAssemblyTable::IsFrameworkAssembly returns false if culture is not neutral.
            // However its caller doesn't initialize the culture and hence the culture is ignored.
            //   PrepQueryMatchData(pName, wzName, &dwSizeName, wzVersion, &dwSizeVer, wzPublicKeyToken, &dwSizePKT, NULL, NULL, NULL);. 

            if (identity.ContentType != AssemblyContentType.Default)
            {
                return false;
            }

            FrameworkAssemblyDictionary.Value value;
            if (!g_arFxPolicy.TryGetValue(identity.Name, out value) ||
                !value.PublicKeyToken.SequenceEqual(identity.PublicKeyToken))
            {
                return false;
            }

            // build and revision numbers are ignored
            uint thisVersion = ((uint)identity.Version.Major << 16) | (uint)identity.Version.Minor;
            uint fxVersion = ((uint)value.Version.Major << 16) | (uint)value.Version.Minor;
            return thisVersion <= fxVersion;
        }
 public bool ReferenceMatchesDefinition(AssemblyIdentity reference, AssemblyIdentity definition)
 {
     return(Compare(reference, referenceDisplayName: null, definition, unificationApplied: out _, ignoreVersion: false) != ComparisonResult.NotEquivalent);
 }
        private static bool IsOptionallyRetargetableAssembly(AssemblyIdentity identity)
        {
            if (!identity.IsRetargetable)
            {
                return false;
            }

            bool retargetable, portable;
            IsRetargetableAssembly(identity, out retargetable, out portable);
            return retargetable && portable;
        }
 public ComparisonResult Compare(AssemblyIdentity reference, AssemblyIdentity definition)
 {
     return(Compare(reference, referenceDisplayName: null, definition, unificationApplied: out _, ignoreVersion: true));
 }
        private static void IsRetargetableAssembly(AssemblyIdentity identity, out bool retargetable, out bool portable)
        {
            retargetable = portable = false;

            if (IsTriviallyNonRetargetable(identity))
            {
                return;
            }

            FrameworkRetargetingDictionary.Value value;
            retargetable = g_arRetargetPolicy.TryGetValue(identity, out value);
            portable = value.IsPortable;
        }
        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);
        }
        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(SILVERLIGHT_PLATFORM_PUBLICKEY_STR_L))
                {
                    if (!policy.SuppressSilverlightPlatformAssembliesPortability)
                    {
                        if (SimpleNameComparer.Equals(identity.Name, "System") ||
                            SimpleNameComparer.Equals(identity.Name, "System.Core"))
                        {
                            newVersion = (Version)VER_ASSEMBLYVERSION_STR_L;
                            newPublicKeyToken = ECMA_PUBLICKEY_STR_L;
                        }
                    }
                }
                else if (identity.PublicKeyToken.SequenceEqual(SILVERLIGHT_PUBLICKEY_STR_L))
                {
                    if (!policy.SuppressSilverlightLibraryAssembliesPortability)
                    {
                        if (SimpleNameComparer.Equals(identity.Name, "Microsoft.VisualBasic"))
                        {
                            newVersion = new Version(10, 0, 0, 0);
                            newPublicKeyToken = MICROSOFT_PUBLICKEY_STR_L;
                        }

                        if (SimpleNameComparer.Equals(identity.Name, "System.ComponentModel.Composition"))
                        {
                            newVersion = (Version)VER_ASSEMBLYVERSION_STR_L;
                            newPublicKeyToken = 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);
        }
예제 #50
0
        /// <summary>
        /// Parses display name filling defaults for any basic properties that are missing.
        /// </summary>
        /// <param name="displayName">Display name.</param>
        /// <param name="identity">A full assembly identity.</param>
        /// <param name="parts">
        /// Parts of the assembly identity that were specified in the display name,
        /// or 0 if the parsing failed.
        /// </param>
        /// <returns>True if display name parsed correctly.</returns>
        /// <remarks>
        /// The simple name has to be non-empty.
        /// A partially specified version might be missing build and/or revision number. The default value for these is 65535.
        /// The default culture is neutral (<see cref="CultureName"/> is <see cref="String.Empty"/>.
        /// If neither public key nor token is specified the identity is considered weak.
        /// </remarks>
        /// <exception cref="ArgumentNullException"><paramref name="displayName"/> is null.</exception>
        public static bool TryParseDisplayName(string displayName, out AssemblyIdentity identity, out AssemblyIdentityParts parts)
        {
            // see ndp\clr\src\Binder\TextualIdentityParser.cpp, ndp\clr\src\Binder\StringLexer.cpp

            identity = null;
            parts    = 0;

            if (displayName == null)
            {
                throw new ArgumentNullException(nameof(displayName));
            }

            if (displayName.IndexOf('\0') >= 0)
            {
                return(false);
            }

            int    position = 0;
            string simpleName;

            if (!TryParseNameToken(displayName, ref position, out simpleName))
            {
                return(false);
            }

            var parsedParts = AssemblyIdentityParts.Name;
            var seen        = AssemblyIdentityParts.Name;

            Version version        = null;
            string  culture        = null;
            bool    isRetargetable = false;
            var     contentType    = AssemblyContentType.Default;
            var     publicKey      = default(ImmutableArray <byte>);
            var     publicKeyToken = default(ImmutableArray <byte>);

            while (position < displayName.Length)
            {
                // Parse ',' name '=' value
                if (displayName[position] != ',')
                {
                    return(false);
                }

                position++;

                string propertyName;
                if (!TryParseNameToken(displayName, ref position, out propertyName))
                {
                    return(false);
                }

                if (position >= displayName.Length || displayName[position] != '=')
                {
                    return(false);
                }

                position++;

                string propertyValue;
                if (!TryParseNameToken(displayName, ref position, out propertyValue))
                {
                    return(false);
                }

                // Process property
                if (string.Equals(propertyName, "Version", StringComparison.OrdinalIgnoreCase))
                {
                    if ((seen & AssemblyIdentityParts.Version) != 0)
                    {
                        return(false);
                    }

                    seen |= AssemblyIdentityParts.Version;

                    if (propertyValue == "*")
                    {
                        continue;
                    }

                    ulong versionLong;
                    AssemblyIdentityParts versionParts;
                    if (!TryParseVersion(propertyValue, out versionLong, out versionParts))
                    {
                        return(false);
                    }

                    version      = ToVersion(versionLong);
                    parsedParts |= versionParts;
                }
                else if (string.Equals(propertyName, "Culture", StringComparison.OrdinalIgnoreCase) ||
                         string.Equals(propertyName, "Language", StringComparison.OrdinalIgnoreCase))
                {
                    if ((seen & AssemblyIdentityParts.Culture) != 0)
                    {
                        return(false);
                    }

                    seen |= AssemblyIdentityParts.Culture;

                    if (propertyValue == "*")
                    {
                        continue;
                    }

                    culture      = string.Equals(propertyValue, InvariantCultureDisplay, StringComparison.OrdinalIgnoreCase) ? null : propertyValue;
                    parsedParts |= AssemblyIdentityParts.Culture;
                }
                else if (string.Equals(propertyName, "PublicKey", StringComparison.OrdinalIgnoreCase))
                {
                    if ((seen & AssemblyIdentityParts.PublicKey) != 0)
                    {
                        return(false);
                    }

                    seen |= AssemblyIdentityParts.PublicKey;

                    if (propertyValue == "*")
                    {
                        continue;
                    }

                    ImmutableArray <byte> value;
                    if (!TryParsePublicKey(propertyValue, out value))
                    {
                        return(false);
                    }

                    // NOTE: Fusion would also set the public key token (as derived from the public key) here.
                    //       We may need to do this as well for error cases, as Fusion would fail to parse the
                    //       assembly name if public key token calculation failed.

                    publicKey    = value;
                    parsedParts |= AssemblyIdentityParts.PublicKey;
                }
                else if (string.Equals(propertyName, "PublicKeyToken", StringComparison.OrdinalIgnoreCase))
                {
                    if ((seen & AssemblyIdentityParts.PublicKeyToken) != 0)
                    {
                        return(false);
                    }

                    seen |= AssemblyIdentityParts.PublicKeyToken;

                    if (propertyValue == "*")
                    {
                        continue;
                    }

                    ImmutableArray <byte> value;
                    if (!TryParsePublicKeyToken(propertyValue, out value))
                    {
                        return(false);
                    }

                    publicKeyToken = value;
                    parsedParts   |= AssemblyIdentityParts.PublicKeyToken;
                }
                else if (string.Equals(propertyName, "Retargetable", StringComparison.OrdinalIgnoreCase))
                {
                    if ((seen & AssemblyIdentityParts.Retargetability) != 0)
                    {
                        return(false);
                    }

                    seen |= AssemblyIdentityParts.Retargetability;

                    if (propertyValue == "*")
                    {
                        continue;
                    }

                    if (string.Equals(propertyValue, "Yes", StringComparison.OrdinalIgnoreCase))
                    {
                        isRetargetable = true;
                    }
                    else if (string.Equals(propertyValue, "No", StringComparison.OrdinalIgnoreCase))
                    {
                        isRetargetable = false;
                    }
                    else
                    {
                        return(false);
                    }

                    parsedParts |= AssemblyIdentityParts.Retargetability;
                }
                else if (string.Equals(propertyName, "ContentType", StringComparison.OrdinalIgnoreCase))
                {
                    if ((seen & AssemblyIdentityParts.ContentType) != 0)
                    {
                        return(false);
                    }

                    seen |= AssemblyIdentityParts.ContentType;

                    if (propertyValue == "*")
                    {
                        continue;
                    }

                    if (string.Equals(propertyValue, "WindowsRuntime", StringComparison.OrdinalIgnoreCase))
                    {
                        contentType = AssemblyContentType.WindowsRuntime;
                    }
                    else
                    {
                        return(false);
                    }

                    parsedParts |= AssemblyIdentityParts.ContentType;
                }
                else
                {
                    parsedParts |= AssemblyIdentityParts.Unknown;
                }
            }

            // incompatible values:
            if (isRetargetable && contentType == AssemblyContentType.WindowsRuntime)
            {
                return(false);
            }

            bool hasPublicKey      = !publicKey.IsDefault;
            bool hasPublicKeyToken = !publicKeyToken.IsDefault;

            identity = new AssemblyIdentity(simpleName, version, culture, hasPublicKey ? publicKey : publicKeyToken, hasPublicKey, isRetargetable, contentType);

            if (hasPublicKey && hasPublicKeyToken && !identity.PublicKeyToken.SequenceEqual(publicKeyToken))
            {
                identity = null;
                return(false);
            }

            parts = parsedParts;
            return(true);
        }
예제 #51
0
 public AnalyzerInfo(string filePath, AssemblyIdentity identity, Guid mvid, ImmutableArray<AssemblyIdentity> references)
 {
     Path = filePath;
     Identity = identity;
     MVID = mvid;
     References = references;
 }
예제 #52
0
        /// <summary>
        /// Parses display name filling defaults for any basic properties that are missing.
        /// </summary>
        /// <param name="displayName">Display name.</param>
        /// <param name="identity">A full assembly identity.</param>
        /// <param name="parts">
        /// Parts of the assembly identity that were specified in the display name,
        /// or 0 if the parsing failed.
        /// </param>
        /// <returns>True if display name parsed correctly.</returns>
        /// <remarks>
        /// The simple name has to be non-empty.
        /// A partially specified version might be missing build and/or revision number. The default value for these is 65535.
        /// The default culture is neutral (<see cref="CultureName"/> is <see cref="String.Empty"/>.
        /// If neither public key nor token is specified the identity is considered weak.
        /// </remarks>
        /// <exception cref="ArgumentNullException"><paramref name="displayName"/> is null.</exception>
        public static bool TryParseDisplayName(string displayName, out AssemblyIdentity identity, out AssemblyIdentityParts parts)
        {
            // see ndp\clr\src\Binder\TextualIdentityParser.cpp, ndp\clr\src\Binder\StringLexer.cpp

            identity = null;
            parts    = 0;

            if (displayName == null)
            {
                throw new ArgumentNullException("displayName");
            }

            if (displayName.IndexOf('\0') >= 0)
            {
                return(false);
            }

            int    position   = 0;
            string simpleName = TryParseNameToken(displayName, ',', ref position);

            if (simpleName == null)
            {
                return(false);
            }

            var parsedParts = AssemblyIdentityParts.Name;
            var seen        = AssemblyIdentityParts.Name;

            Version version        = null;
            string  culture        = null;
            bool    isRetargetable = false;
            var     contentType    = AssemblyContentType.Default;
            var     publicKey      = default(ImmutableArray <byte>);
            var     publicKeyToken = default(ImmutableArray <byte>);

            while (position < displayName.Length)
            {
                string propertyName = TryParseNameToken(displayName, '=', ref position);
                if (propertyName == null)
                {
                    return(false);
                }

                string propertyValue = TryParseNameToken(displayName, ',', ref position);
                if (propertyValue == null)
                {
                    return(false);
                }

                if (string.Equals(propertyName, "Version", StringComparison.OrdinalIgnoreCase))
                {
                    if ((seen & AssemblyIdentityParts.Version) != 0)
                    {
                        return(false);
                    }

                    seen |= AssemblyIdentityParts.Version;

                    if (propertyValue == "*")
                    {
                        continue;
                    }

                    ulong versionLong;
                    AssemblyIdentityParts versionParts;
                    if (!TryParseVersion(propertyValue, out versionLong, out versionParts))
                    {
                        return(false);
                    }

                    version      = ToVersion(versionLong);
                    parsedParts |= versionParts;
                }
                else if (string.Equals(propertyName, "Culture", StringComparison.OrdinalIgnoreCase) ||
                         string.Equals(propertyName, "Language", StringComparison.OrdinalIgnoreCase))
                {
                    if ((seen & AssemblyIdentityParts.Culture) != 0)
                    {
                        return(false);
                    }

                    seen |= AssemblyIdentityParts.Culture;

                    if (propertyValue == "*")
                    {
                        continue;
                    }

                    culture      = string.Equals(propertyValue, "neutral", StringComparison.OrdinalIgnoreCase) ? null : propertyValue;
                    parsedParts |= AssemblyIdentityParts.Culture;
                }
                else if (string.Equals(propertyName, "PublicKey", StringComparison.OrdinalIgnoreCase))
                {
                    if ((seen & AssemblyIdentityParts.PublicKey) != 0)
                    {
                        return(false);
                    }

                    seen |= AssemblyIdentityParts.PublicKey;

                    if (propertyValue == "*")
                    {
                        continue;
                    }

                    ImmutableArray <byte> value = ParseKey(propertyValue);
                    if (value.Length == 0)
                    {
                        return(false);
                    }

                    publicKey    = value;
                    parsedParts |= AssemblyIdentityParts.PublicKey;
                }
                else if (string.Equals(propertyName, "PublicKeyToken", StringComparison.OrdinalIgnoreCase))
                {
                    if ((seen & AssemblyIdentityParts.PublicKeyToken) != 0)
                    {
                        return(false);
                    }

                    seen |= AssemblyIdentityParts.PublicKeyToken;

                    if (propertyValue == "*")
                    {
                        continue;
                    }

                    ImmutableArray <byte> value;
                    if (string.Equals(propertyValue, "null", StringComparison.OrdinalIgnoreCase) ||
                        string.Equals(propertyValue, "neutral", StringComparison.OrdinalIgnoreCase))
                    {
                        value = ImmutableArray.Create <byte>();
                    }
                    else
                    {
                        value = ParseKey(propertyValue);
                        if (value.Length != PublicKeyTokenSize)
                        {
                            return(false);
                        }
                    }

                    publicKeyToken = value;
                    parsedParts   |= AssemblyIdentityParts.PublicKeyToken;
                }
                else if (string.Equals(propertyName, "Retargetable", StringComparison.OrdinalIgnoreCase))
                {
                    if ((seen & AssemblyIdentityParts.Retargetability) != 0)
                    {
                        return(false);
                    }

                    seen |= AssemblyIdentityParts.Retargetability;

                    if (propertyValue == "*")
                    {
                        continue;
                    }

                    if (string.Equals(propertyValue, "Yes", StringComparison.OrdinalIgnoreCase))
                    {
                        isRetargetable = true;
                    }
                    else if (string.Equals(propertyValue, "No", StringComparison.OrdinalIgnoreCase))
                    {
                        isRetargetable = false;
                    }
                    else
                    {
                        return(false);
                    }

                    parsedParts |= AssemblyIdentityParts.Retargetability;
                }
                else if (string.Equals(propertyName, "ContentType", StringComparison.OrdinalIgnoreCase))
                {
                    if ((seen & AssemblyIdentityParts.ContentType) != 0)
                    {
                        return(false);
                    }

                    seen |= AssemblyIdentityParts.ContentType;

                    if (propertyValue == "*")
                    {
                        continue;
                    }

                    if (string.Equals(propertyValue, "WindowsRuntime", StringComparison.OrdinalIgnoreCase))
                    {
                        contentType = AssemblyContentType.WindowsRuntime;
                    }
                    else
                    {
                        return(false);
                    }

                    parsedParts |= AssemblyIdentityParts.ContentType;
                }
                else
                {
                    parsedParts |= AssemblyIdentityParts.Unknown;
                }
            }

            // incompatible values:
            if (isRetargetable && contentType == AssemblyContentType.WindowsRuntime)
            {
                return(false);
            }

            bool hasPublicKey      = !publicKey.IsDefault;
            bool hasPublicKeyToken = !publicKeyToken.IsDefault;

            identity = new AssemblyIdentity(simpleName, version, culture, hasPublicKey ? publicKey : publicKeyToken, hasPublicKey, isRetargetable, contentType);

            if (hasPublicKey && hasPublicKeyToken && !identity.PublicKeyToken.SequenceEqual(publicKeyToken))
            {
                identity = null;
                return(false);
            }

            parts = parsedParts;
            return(true);
        }
예제 #53
0
 internal static bool IsReservedAssemblyName(AssemblyIdentity identity)
 {
     return identity.Name.StartsWith(s_globalAssemblyNamePrefix);
 }
예제 #54
0
 public abstract void ReportDuplicateMetadataReferenceWeak(DiagnosticBag diagnostics, Location location, MetadataReference reference, AssemblyIdentity identity, MetadataReference equivalentReference, AssemblyIdentity equivalentIdentity);
예제 #55
0
            public CollectibleCodeManager(AssemblyLoader assemblyLoader, string assemblyNamePrefix)
            {
                this.assemblyLoader = assemblyLoader;
                _dynamicAssemblyName = new AssemblyIdentity(name: assemblyNamePrefix + "CD");

                AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(Resolve);
            }
예제 #56
0
 // Windows[.winmd]
 private static bool IsWindowsRuntime(AssemblyIdentity identity)
 {
     return((identity.ContentType == AssemblyContentType.WindowsRuntime) &&
            string.Equals(identity.Name, "windows", StringComparison.OrdinalIgnoreCase));
 }
예제 #57
0
            internal UncollectibleCodeManager(AssemblyLoader assemblyLoader, string assemblyNamePrefix)
            {
                _assemblyLoader = assemblyLoader;
                _assemblyNamePrefix = assemblyNamePrefix;
                this.dynamicAssemblyName = new AssemblyIdentity(name: assemblyNamePrefix + "UD");

                AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(Resolve);
            }
예제 #58
0
 public ReferencedAssemblyIdentity(AssemblyIdentity identity, MetadataReference reference, int relativeAssemblyIndex)
 {
     Identity              = identity;
     Reference             = reference;
     RelativeAssemblyIndex = relativeAssemblyIndex;
 }
예제 #59
0
 protected abstract bool WeakIdentityPropertiesEquivalent(AssemblyIdentity identity1, AssemblyIdentity identity2);
예제 #60
0
        public bool Contains(AssemblyIdentity identity, bool allowHigherVersion = true)
        {
            TValue value;

            return(TryGetValue(identity, out value, allowHigherVersion));
        }