public AssemblyUsageInfo(AssemblyInfo assembly, int targetsCount)
        {
            SourceAssembly = assembly;

            // Initialize the target information
            UsageData = new List<TargetUsageInfo>(targetsCount);
            for (int i = 0; i < targetsCount; i++)
            {
                UsageData.Add(new TargetUsageInfo());
            }
        }
 public void AddMissingMember(MissingMemberInfo mmi, AssemblyInfo sourceAssembly)
 {
     var x = MissingMembers.FirstOrDefault(m => m.MemberName == mmi.MemberName);
     if (x != null)
     {
         x.IncrementUsage(sourceAssembly);
     }
     else
     {
         MissingMembers.Add(mmi);
     }
 }
        public MissingMemberInfo(AssemblyInfo sourceAssembly, string DocId, List<Version> targetStatus, string recommendedChanges)
            : base(DocId)
        {
            RecommendedChanges = recommendedChanges;
            MemberName = DocId;
            TargetStatus = targetStatus?.Select(GenerateTargetStatusMessage).ToList() ?? Enumerable.Empty<string>();
            TargetVersionStatus = new List<Version>(targetStatus ?? Enumerable.Empty<Version>());

            _usedInAssemblies = new HashSet<AssemblyInfo>();

            if (sourceAssembly != null)
            {
                _usedInAssemblies.Add(sourceAssembly);
            }
        }
        public MissingTypeInfo(AssemblyInfo sourceAssembly, string docId, List<Version> targetStatus, string recommendedChanges)
            : base(docId)
        {
            int pos = DocId.IndexOf("T:");
            if (pos == -1)
                throw new ArgumentException(LocalizedStrings.MemberShouldBeDefinedOnTypeException, "docId");

            TypeName = DocId.Substring(pos);
            MissingMembers = new HashSet<MissingMemberInfo>();
            TargetStatus = targetStatus?.Select(GenerateTargetStatusMessage).ToList() ?? Enumerable.Empty<string>();
            TargetVersionStatus = new List<Version>(targetStatus ?? Enumerable.Empty<Version>());

            RecommendedChanges = recommendedChanges;
            _usedInAssemblies = new HashSet<AssemblyInfo>();

            if (sourceAssembly != null)
            {
                _usedInAssemblies.Add(sourceAssembly);
            }
        }
        public DependencyFinderEngineHelper(IDependencyFilter assemblyFilter, MetadataReader metadataReader, IAssemblyFile file)
        {
            _assemblyFilter = assemblyFilter;
            _reader = metadataReader;
            _assemblyLocation = file.Name;

            MemberDependency = new List<MemberDependency>();
            CallingAssembly = new AssemblyInfo
            {
                AssemblyIdentity = metadataReader.FormatAssemblyInfo().ToString(),
                FileVersion = file.Version ?? string.Empty,
                TargetFrameworkMoniker = metadataReader.GetTargetFrameworkMoniker() ?? string.Empty
            };

            // Get assembly info
            var assemblyDefinition = _reader.GetAssemblyDefinition();

            _currentAssemblyInfo = _reader.FormatAssemblyInfo(assemblyDefinition);
            _currentAssemblyName = _reader.GetString(assemblyDefinition.Name);
        }
        public void AddMissingDependency(AssemblyInfo SourceAssembly, MemberInfo missingDependency, string recommendedChanges)
        {
            MissingTypeInfo typeInfo;
            try
            {
                var type = _types[Tuple.Create(missingDependency.DefinedInAssemblyIdentity, (missingDependency.TypeDocId ?? missingDependency.MemberDocId))];
                typeInfo = new MissingTypeInfo(SourceAssembly, type.MemberDocId, type.TargetStatus, type.RecommendedChanges);
            }
            catch (KeyNotFoundException)
            {
                typeInfo = new MissingTypeInfo(SourceAssembly, missingDependency.TypeDocId ?? missingDependency.MemberDocId, missingDependency.TargetStatus, recommendedChanges);
            }

            // If we already have an entry for this type, get it.
            if (_missingTypes.Any(mt => mt.TypeName == typeInfo.TypeName))
            {
                typeInfo = _missingTypes.First(mt => mt.TypeName == typeInfo.TypeName);
                typeInfo.IncrementUsage(SourceAssembly);
            }
            else
            {
                _missingTypes.Add(typeInfo);
            }

            // If we did not receive a member entry, it means the entire type is missing -- flag it accordingly
            if (missingDependency.MemberDocId.StartsWith("M:", System.StringComparison.OrdinalIgnoreCase) ||
                missingDependency.MemberDocId.StartsWith("F:", System.StringComparison.OrdinalIgnoreCase) ||
                missingDependency.MemberDocId.StartsWith("P:", System.StringComparison.OrdinalIgnoreCase))
            {
                MissingMemberInfo memberInfo = new MissingMemberInfo(SourceAssembly, missingDependency.MemberDocId, missingDependency.TargetStatus, recommendedChanges);
                typeInfo.AddMissingMember(memberInfo, SourceAssembly);
            }
            else
            {
                typeInfo.MarkAsMissing();
            }
        }
        private static IDictionary<MemberInfo, ICollection<AssemblyInfo>> GenerateTestData(IApiCatalogLookup catalog)
        {
            var userAsm1 = new AssemblyInfo { AssemblyIdentity = "userAsm1, Version=1.0.0.0", FileVersion = "1.0.0.0" };
            var userAsm2 = new AssemblyInfo { AssemblyIdentity = "userAsm2, Version=2.0.0.0", FileVersion = "2.0.0.0" };
            var userAsm3 = new AssemblyInfo { AssemblyIdentity = "userAsm3, Version=3.0.0.0", FileVersion = "3.0.0.0" };
            var mi1 = new MemberInfo { DefinedInAssemblyIdentity = "System.Drawing, Version=1.0.136.0, PublicKeyToken=b03f5f7f11d50a3a", MemberDocId = TestDocId1 };
            var mi2 = new MemberInfo { DefinedInAssemblyIdentity = "System.Data, Version=1.0.136.0, PublicKeyToken=b77a5c561934e089", MemberDocId = TestDocId2 };
            var mi3 = new MemberInfo { DefinedInAssemblyIdentity = "userAsm1, Version=1.0.0.0", MemberDocId = "T:MyType" };

            catalog.IsFrameworkAssembly(GetAssemblyIdentityWithoutCultureAndVersion(mi1.DefinedInAssemblyIdentity)).Returns(true);
            catalog.IsFrameworkAssembly(GetAssemblyIdentityWithoutCultureAndVersion(mi2.DefinedInAssemblyIdentity)).Returns(true);
            catalog.IsFrameworkMember(mi1.MemberDocId).Returns(true);
            catalog.IsFrameworkMember(mi2.MemberDocId).Returns(true);

            return new Dictionary<MemberInfo, ICollection<AssemblyInfo>>
            {
                {mi1, new[] { userAsm1 } },
                {mi2, new[] { userAsm2 } },
                {mi3, new[] { userAsm3 } },
            };
        }
        public void FindMembersNotInTargetsWithSuppliedAssembly()
        {
            var testData = new Dictionary<MemberInfo, ICollection<AssemblyInfo>>();

            var userAsm1 = new AssemblyInfo() { AssemblyIdentity = "userAsm1, Version=1.0.0.0", FileVersion = "1.0.0.0" };
            var userAsm2 = new AssemblyInfo() { AssemblyIdentity = "userAsm2, Version=2.0.0.0", FileVersion = "2.0.0.0" };
            var userAsm3 = new AssemblyInfo() { AssemblyIdentity = "userAsm3, Version=3.0.0.0", FileVersion = "3.0.0.0" };
            var mi1 = new MemberInfo() { DefinedInAssemblyIdentity = "System.Drawing, Version=1.0.136.0, PublicKeyToken=b03f5f7f11d50a3a", MemberDocId = "T:System.Drawing.Color" };
            var mi2 = new MemberInfo() { DefinedInAssemblyIdentity = "System.Data, Version=1.0.136.0, PublicKeyToken=b77a5c561934e089", MemberDocId = "T:System.Data.SqlTypes.SqlBoolean" };
            var mi3 = new MemberInfo() { DefinedInAssemblyIdentity = "userAsm1, Version=1.0.0.0", MemberDocId = "T:MyType" };

            var usedIn1 = new HashSet<AssemblyInfo>() { userAsm1, userAsm2 };
            testData.Add(mi1, usedIn1);

            var usedIn2 = new HashSet<AssemblyInfo>() { userAsm2, userAsm3 };
            testData.Add(mi2, usedIn2);
            testData.Add(mi3, usedIn2);

            var targets = new List<FrameworkName>() { new FrameworkName("Windows Phone, version=8.1") };

            var catalog = Substitute.For<IApiCatalogLookup>();
            catalog.IsFrameworkAssembly(GetAssemblyIdentityWithoutCultureAndVersion(mi1.DefinedInAssemblyIdentity)).Returns(true);
            catalog.IsFrameworkAssembly(GetAssemblyIdentityWithoutCultureAndVersion(mi2.DefinedInAssemblyIdentity)).Returns(true);
            catalog.IsFrameworkMember(mi1.MemberDocId).Returns(true);
            catalog.IsFrameworkMember(mi2.MemberDocId).Returns(true);

            var recommendations = Substitute.For<IApiRecommendations>();
            var engine = new AnalysisEngine(catalog, recommendations);
            var notInTarget = engine.FindMembersNotInTargets(targets, new[] { mi1.DefinedInAssemblyIdentity }, testData);

            Assert.Equal(1, notInTarget.Count);
        }
 public void IncrementUsage(AssemblyInfo sourceAssembly)
 {
     _usedInAssemblies.Add(sourceAssembly);
 }
        private IEnumerable<MemberDependency> GetDependencies(string assemblyLocation)
        {
            using (var host = new HostEnvironment())
            {
                host.UnableToResolve += (s, e) =>
                {
                    string callingAssembly = e.Referrer.FullName();

                    // Try to get better information about the referrer. This may throw, but we don't want to crash even if we do.
                    try
                    {
                        callingAssembly = e.Referrer.GetAssemblyReference().AssemblyIdentity.Format();
                    }
                    catch { }

                    HashSet<string> newValue = new HashSet<string>();
                    newValue.Add(callingAssembly);
                    _unresolvedAssemblies.AddOrUpdate(e.Unresolved.Format(), newValue, (key, existingHashSet) =>
                    {
                        lock (existingHashSet)
                        {
                            existingHashSet.Add(callingAssembly);
                        }
                        return existingHashSet;
                    });
                };

                host.UnifyToLibPath = true;
                var cciAssembly = host.LoadAssembly(assemblyLocation);

                if (cciAssembly == null)
                {
                    _assembliesWithError.Add(assemblyLocation);
                    // error.
                    yield break;
                }


                // Extract the fileversion and assembly version from the assembly.
                FileVersionInfo fileInfo = FileVersionInfo.GetVersionInfo(assemblyLocation);
                AssemblyInfo assemblyInfo = new AssemblyInfo();
                assemblyInfo.AssemblyIdentity = cciAssembly.AssemblyIdentity.Format();
                assemblyInfo.FileVersion = fileInfo.FileVersion ?? string.Empty;
                assemblyInfo.TargetFrameworkMoniker = cciAssembly.GetTargetFrameworkMoniker();

                // remember this assembly as a user assembly.
                _userAssemblies.Add(assemblyInfo);

                // Identify references to members (generic and non-generic)
                foreach (var reference in cciAssembly.GetTypeMemberReferences())
                {
                    if (reference.ContainingType.GetAssemblyReference() == null)
                        continue;

                    string definedIn = reference.ContainingType.GetAssemblyReference().ContainingAssembly.AssemblyIdentity.Format();
                    // return the type
                    yield return new MemberDependency()
                    {
                        CallingAssembly = assemblyInfo,
                        MemberDocId = reference.ContainingType.DocId(),
                        DefinedInAssemblyIdentity = definedIn
                    };

                    //return the member
                    yield return new MemberDependency()
                    {
                        CallingAssembly = assemblyInfo,
                        MemberDocId = reference.DocId(),
                        TypeDocId = reference.ContainingType.DocId(),
                        DefinedInAssemblyIdentity = definedIn
                    };
                }

                // Identify references to types
                foreach (var refence in cciAssembly.GetTypeReferences())
                {
                    string definedIn = refence.GetAssemblyReference().ContainingAssembly.AssemblyIdentity.Format();
                    //return the type
                    yield return new MemberDependency()
                    {
                        CallingAssembly = assemblyInfo,
                        MemberDocId = refence.DocId(),
                        DefinedInAssemblyIdentity = definedIn
                    };
                }
            }
        }
 public string GetNameForAssemblyInfo(AssemblyInfo assembly)
 {
     return _assemblyNameMap == null ? string.Empty : _assemblyNameMap[assembly];
 }