예제 #1
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.
                if (_loadedAssembliesByIdentity.TryGetValue(identity, out var 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);
            }
        }
예제 #2
0
 internal void AddAssembliesToReference(IEnumerable <Assembly> assemblies)
 {
     AddAssembliesToReference
     (
         assemblies,
         (assembly) => AssemblyIdentity.FromAssemblyDefinition(assembly),
         (assembly) => assembly.ToRef()
     );
 }
예제 #3
0
        public void FromAssemblyDefinitionInvalidParameters()
        {
            Assembly asm = null;

            Assert.Throws <ArgumentNullException>(
                () =>
            {
                AssemblyIdentity.FromAssemblyDefinition(asm);
            }
                );
        }
예제 #4
0
 /// <summary>
 /// Determines whether this help item is about a type that is contained in one of the provided assemblies.
 /// </summary>
 /// <param name="assemblies">The assemblies to test.</param>
 /// <returns>If the help item concerns an issue that is in one of the provided assemblies, then this assembly is returned; otherwise, the return value is null.</returns>
 public System.Reflection.Assembly GetOneOfTheseAssembliesOrNull(IEnumerable <System.Reflection.Assembly> assemblies)
 {
     foreach (var ass in assemblies)
     {
         if (AssemblyIdentity == AssemblyIdentity.FromAssemblyDefinition(ass))
         {
             return(ass);
         }
     }
     return(null);
 }
예제 #5
0
        public void FromAssemblyDefinition_InvariantCulture()
        {
            var name = new AssemblyName("goo");

            name.Flags                 = AssemblyNameFlags.None;
            name.CultureInfo           = CultureInfo.InvariantCulture;
            name.ContentType           = AssemblyContentType.Default;
            name.Version               = new Version(1, 2, 3, 4);
            name.ProcessorArchitecture = ProcessorArchitecture.X86;

            var id = AssemblyIdentity.FromAssemblyDefinition(name);

            Assert.Equal("", id.CultureName);
        }
예제 #6
0
        private Assembly TryGetAssemblyLoadedFromPath(AssemblyIdentity identity, string directory)
        {
            string pathWithoutExtension = Path.Combine(directory, identity.Name);

            foreach (var extension in RuntimeMetadataReferenceResolver.AssemblyExtensions)
            {
                if (_assembliesLoadedFromLocationByFullPath.TryGetValue(pathWithoutExtension + extension, out var assemblyAndLocation) &&
                    identity.Equals(AssemblyIdentity.FromAssemblyDefinition(assemblyAndLocation.Assembly)))
                {
                    return(assemblyAndLocation.Assembly);
                }
            }

            return(null);
        }
예제 #7
0
        private void RegisterLoadedAssemblySimpleNameNoLock(Assembly assembly, string locationOpt)
        {
            var identity = AssemblyIdentity.FromAssemblyDefinition(assembly);
            var info     = new LoadedAssemblyInfo(assembly, identity, locationOpt);

            if (_loadedAssembliesBySimpleName.TryGetValue(identity.Name, out var existingInfos))
            {
                existingInfos.Add(info);
            }
            else
            {
                _loadedAssembliesBySimpleName.Add(identity.Name, new List <LoadedAssemblyInfo> {
                    info
                });
            }
        }
예제 #8
0
        private static Assembly FindHighestVersionOrFirstMatchingIdentity(AssemblyIdentity identity, IEnumerable <Assembly> assemblies)
        {
            Assembly candidate        = null;
            Version  candidateVersion = null;

            foreach (var assembly in assemblies)
            {
                var assemblyIdentity = AssemblyIdentity.FromAssemblyDefinition(assembly);
                if (DesktopAssemblyIdentityComparer.Default.ReferenceMatchesDefinition(identity, assemblyIdentity))
                {
                    if (candidate == null || candidateVersion < assemblyIdentity.Version)
                    {
                        candidate        = assembly;
                        candidateVersion = assemblyIdentity.Version;
                    }
                }
            }

            return(candidate);
        }
예제 #9
0
        public void FromAssemblyDefinition()
        {
            var name = new AssemblyName("goo");

            name.Flags =
                AssemblyNameFlags.Retargetable
                | AssemblyNameFlags.PublicKey
                | AssemblyNameFlags.EnableJITcompileOptimizer
                | AssemblyNameFlags.EnableJITcompileTracking;
            name.CultureInfo           = new CultureInfo("en-US", useUserOverride: false);
            name.ContentType           = AssemblyContentType.Default;
            name.Version               = new Version(1, 2, 3, 4);
            name.ProcessorArchitecture = ProcessorArchitecture.X86;

            var id = AssemblyIdentity.FromAssemblyDefinition(name);

            Assert.Equal("goo", id.Name);
            Assert.True(id.IsRetargetable);
            Assert.Equal(new Version(1, 2, 3, 4), id.Version);
            Assert.Equal(AssemblyContentType.Default, id.ContentType);
            Assert.False(id.HasPublicKey);
            Assert.False(id.IsStrongName);

            name = new AssemblyName("goo");
            name.SetPublicKey(PublicKey1);
            name.Version = new Version(1, 2, 3, 4);

            id = AssemblyIdentity.FromAssemblyDefinition(name);
            Assert.Equal("goo", id.Name);
            Assert.Equal(new Version(1, 2, 3, 4), id.Version);
            Assert.True(id.HasPublicKey);
            Assert.True(id.IsStrongName);
            AssertEx.Equal(id.PublicKey, PublicKey1);

            name             = new AssemblyName("goo");
            name.ContentType = AssemblyContentType.WindowsRuntime;

            id = AssemblyIdentity.FromAssemblyDefinition(name);
            Assert.Equal("goo", id.Name);
            Assert.Equal(AssemblyContentType.WindowsRuntime, id.ContentType);
        }
예제 #10
0
        // Method is static to prevent accidental use of mutable state in this class
        private static void AnalyzeAndReportConflictsInSolution(
            Solution solution,
            ImmutableHashSet <string> currentAnalyzerPaths,
            HostDiagnosticUpdateSource hostDiagnosticUpdateSource,
            CancellationToken cancellationToken)
        {
            var loadedAssemblies     = AppDomain.CurrentDomain.GetAssemblies().Select(assembly => AssemblyIdentity.FromAssemblyDefinition(assembly));
            var loadedAssembliesList = new IgnorableAssemblyIdentityList(loadedAssemblies);

            var ignorableAssemblyLists = new[] { s_systemPrefixList, s_codeAnalysisPrefixList, s_explicitlyIgnoredAssemblyList, s_assembliesIgnoredByNameList, loadedAssembliesList };

            cancellationToken.ThrowIfCancellationRequested();

            var results = AnalyzerDependencyChecker.ComputeDependencyConflicts(currentAnalyzerPaths, ignorableAssemblyLists, s_bindingRedirectionService, cancellationToken);

            var builder = ImmutableArray.CreateBuilder <DiagnosticData>();

            var conflicts           = results.Conflicts;
            var missingDependencies = results.MissingDependencies;

            foreach (var project in solution.Projects)
            {
                builder.Clear();

                // If our analysis has been cancelled, it means another request has been queued behind us; thus it's OK to stop
                // doing the analysis now and let that other one fix up any stale results.
                cancellationToken.ThrowIfCancellationRequested();

                var analyzerFilePaths = new HashSet <string>(
                    project.AnalyzerReferences
                    .OfType <AnalyzerFileReference>()
                    .Select(f => f.FullPath),
                    StringComparer.OrdinalIgnoreCase);

                foreach (var conflict in conflicts)
                {
                    if (analyzerFilePaths.Contains(conflict.AnalyzerFilePath1) ||
                        analyzerFilePaths.Contains(conflict.AnalyzerFilePath2))
                    {
                        var messageArguments = new string[] { conflict.AnalyzerFilePath1, conflict.AnalyzerFilePath2, conflict.Identity.ToString() };
                        if (DiagnosticData.TryCreate(s_analyzerDependencyConflictRule, messageArguments, project.Id, solution.Workspace, out var diagnostic))
                        {
                            builder.Add(diagnostic);
                        }
                    }
                }

                foreach (var missingDependency in missingDependencies)
                {
                    if (analyzerFilePaths.Contains(missingDependency.AnalyzerPath))
                    {
                        var messageArguments = new string[] { missingDependency.AnalyzerPath, missingDependency.DependencyIdentity.ToString() };
                        if (DiagnosticData.TryCreate(s_missingAnalyzerReferenceRule, messageArguments, project.Id, solution.Workspace, out var diagnostic))
                        {
                            builder.Add(diagnostic);
                        }
                    }
                }

                hostDiagnosticUpdateSource.UpdateDiagnosticsForProject(project.Id, s_dependencyConflictErrorId, builder.ToImmutable());
            }

            foreach (var conflict in conflicts)
            {
                LogConflict(conflict);
            }

            foreach (var missingDependency in missingDependencies)
            {
                LogMissingDependency(missingDependency);
            }
        }
예제 #11
0
        /// <summary>
        /// Resolves <see cref="System.Type"/> to a <see cref="TypeSymbol"/> available in this assembly
        /// its referenced assemblies.
        /// </summary>
        /// <param name="type">The type to resolve.</param>
        /// <param name="includeReferences">Use referenced assemblies for resolution.</param>
        /// <returns>The resolved symbol if successful or null on failure.</returns>
        internal TypeSymbol GetTypeByReflectionType(Type type, bool includeReferences)
        {
            System.Reflection.TypeInfo typeInfo = type.GetTypeInfo();

            Debug.Assert(!typeInfo.IsByRef);

            // not supported rigth now (we don't accept open types as submission results nor host types):
            Debug.Assert(!typeInfo.ContainsGenericParameters);

            if (typeInfo.IsArray)
            {
                TypeSymbol symbol = GetTypeByReflectionType(typeInfo.GetElementType(), includeReferences);
                if ((object)symbol == null)
                {
                    return(null);
                }

                int rank = typeInfo.GetArrayRank();
                return(new ArrayTypeSymbol(this, symbol, ImmutableArray <CustomModifier> .Empty, rank));
            }
            else if (typeInfo.IsPointer)
            {
                TypeSymbol symbol = GetTypeByReflectionType(typeInfo.GetElementType(), includeReferences);
                if ((object)symbol == null)
                {
                    return(null);
                }

                return(new PointerTypeSymbol(symbol));
            }
            else if (typeInfo.DeclaringType != null)
            {
                Debug.Assert(!typeInfo.IsArray);

                // consolidated generic arguments (includes arguments of all declaring types):
                Type[] genericArguments  = typeInfo.GenericTypeArguments;
                int    typeArgumentIndex = 0;

                var currentTypeInfo = typeInfo.IsGenericType ? typeInfo.GetGenericTypeDefinition().GetTypeInfo() : typeInfo;
                var nestedTypes     = ArrayBuilder <System.Reflection.TypeInfo> .GetInstance();

                while (true)
                {
                    Debug.Assert(currentTypeInfo.IsGenericTypeDefinition || !currentTypeInfo.IsGenericType);

                    nestedTypes.Add(currentTypeInfo);
                    if (currentTypeInfo.DeclaringType == null)
                    {
                        break;
                    }

                    currentTypeInfo = currentTypeInfo.DeclaringType.GetTypeInfo();
                }

                int i      = nestedTypes.Count - 1;
                var symbol = (NamedTypeSymbol)GetTypeByReflectionType(nestedTypes[i].AsType(), includeReferences);
                if ((object)symbol == null)
                {
                    return(null);
                }

                while (--i >= 0)
                {
                    int forcedArity         = nestedTypes[i].GenericTypeParameters.Length - nestedTypes[i + 1].GenericTypeParameters.Length;
                    MetadataTypeName mdName = MetadataTypeName.FromTypeName(nestedTypes[i].Name, forcedArity: forcedArity);

                    symbol = symbol.LookupMetadataType(ref mdName);
                    if ((object)symbol == null || symbol.IsErrorType())
                    {
                        return(null);
                    }

                    symbol = ApplyGenericArguments(symbol, genericArguments, ref typeArgumentIndex, includeReferences);
                    if ((object)symbol == null)
                    {
                        return(null);
                    }
                }

                nestedTypes.Free();
                Debug.Assert(typeArgumentIndex == genericArguments.Length);
                return(symbol);
            }
            else
            {
                AssemblyIdentity assemblyId = AssemblyIdentity.FromAssemblyDefinition(typeInfo.Assembly);

                MetadataTypeName mdName = MetadataTypeName.FromNamespaceAndTypeName(
                    typeInfo.Namespace ?? string.Empty,
                    typeInfo.Name,
                    forcedArity: typeInfo.GenericTypeArguments.Length);

                NamedTypeSymbol symbol = GetTopLevelTypeByMetadataName(ref mdName, assemblyId, includeReferences, isWellKnownType: false);

                if ((object)symbol == null || symbol.IsErrorType())
                {
                    return(null);
                }

                int    typeArgumentIndex = 0;
                Type[] genericArguments  = typeInfo.GenericTypeArguments;
                symbol = ApplyGenericArguments(symbol, genericArguments, ref typeArgumentIndex, includeReferences);
                Debug.Assert(typeArgumentIndex == genericArguments.Length);
                return(symbol);
            }
        }
        private Task <AnalyzerDependencyResults> GetConflictsAsync()
        {
            ImmutableHashSet <string> currentAnalyzerPaths = _workspace.CurrentSolution
                                                             .Projects
                                                             .SelectMany(p => p.AnalyzerReferences)
                                                             .OfType <AnalyzerFileReference>()
                                                             .Select(a => a.FullPath)
                                                             .ToImmutableHashSet(StringComparer.OrdinalIgnoreCase);

            if (currentAnalyzerPaths.SetEquals(_analyzerPaths))
            {
                return(_task);
            }

            _cancellationTokenSource.Cancel();
            _cancellationTokenSource = new CancellationTokenSource();
            _analyzerPaths           = currentAnalyzerPaths;

            _task = _task.SafeContinueWith(_ =>
            {
                IEnumerable <AssemblyIdentity> loadedAssemblies    = AppDomain.CurrentDomain.GetAssemblies().Select(assembly => AssemblyIdentity.FromAssemblyDefinition(assembly));
                IgnorableAssemblyIdentityList loadedAssembliesList = new IgnorableAssemblyIdentityList(loadedAssemblies);

                IIgnorableAssemblyList[] ignorableAssemblyLists = new[] { s_systemPrefixList, s_codeAnalysisPrefixList, s_explicitlyIgnoredAssemblyList, s_assembliesIgnoredByNameList, loadedAssembliesList };
                return(new AnalyzerDependencyChecker(currentAnalyzerPaths, ignorableAssemblyLists, _bindingRedirectionService).Run(_cancellationTokenSource.Token));
            },
                                           TaskScheduler.Default);

            return(_task);
        }