private void FindDependencies(IProgressTask progressTask) { var dependencies = new ConcurrentDictionary<MemberInfo, ICollection<AssemblyInfo>>(); _inputAssemblies.AsParallel().ForAll(filename => { foreach (var dep in GetDependencies(filename)) { MemberInfo m = new MemberInfo() { MemberDocId = dep.MemberDocId, TypeDocId = dep.TypeDocId, DefinedInAssemblyIdentity = dep.DefinedInAssemblyIdentity }; // Add this memberinfo HashSet<AssemblyInfo> newassembly = new HashSet<AssemblyInfo>(); newassembly.Add(dep.CallingAssembly); ICollection<AssemblyInfo> assemblies = dependencies.AddOrUpdate(m, newassembly, (key, existingSet) => { lock (existingSet) { existingSet.Add(dep.CallingAssembly); } return existingSet; }); } progressTask.ReportUnitComplete(); }); _cachedDependencies = dependencies; }
public void AddMissingDependency_MissingMemberOfSupportedType_TypeIsNotMarkedMissing() { var targets = TargetPlatforms(2); var type = new MemberInfo { MemberDocId = "T:Spam.Spam", IsSupportedAcrossTargets = true, TargetStatus = targets.Select(t => new Version(t.Version.ToString())).ToList() }; var missingMember = MissingMember(type.MemberDocId, "Eggs"); missingMember.TargetStatus = new List<Version> { new Version("1.0"), null }; var reportingResult = new ReportingResult(targets, new List<MemberInfo>() { type }, Guid.NewGuid().ToString(), AnalyzeRequestFlags.None); reportingResult.AddMissingDependency(null, missingMember, "Add more spam."); var typeIsMarkedMissing = reportingResult.GetMissingTypes() .First(t => string.Equals(t.TypeName, type.MemberDocId, StringComparison.Ordinal)) .IsMissing; Assert.False(typeIsMarkedMissing); }
public MemberInfoV1(MemberInfo memberInfo) { TargetStatus = memberInfo.TargetStatus == null ? null : memberInfo.TargetStatus.Select(GetTargetStatusMessage).ToList(); DefinedInAssemblyIdentity = memberInfo.DefinedInAssemblyIdentity; MemberDocId = memberInfo.MemberDocId; TypeDocId = memberInfo.TypeDocId; RecommendedChanges = memberInfo.RecommendedChanges; }
private void FindDependencies(IProgressReporter progressReport) { _inputAssemblies.AsParallel().ForAll(file => { try { foreach (var dependencies in GetDependencies(file)) { var m = new MemberInfo { MemberDocId = dependencies.MemberDocId, TypeDocId = dependencies.TypeDocId, DefinedInAssemblyIdentity = dependencies.DefinedInAssemblyIdentity?.ToString() }; if (m.DefinedInAssemblyIdentity == null && !dependencies.IsPrimitive) { throw new InvalidOperationException("All non-primitive types should be defined in an assembly"); } // Add this memberinfo var newassembly = new HashSet<AssemblyInfo> { dependencies.CallingAssembly }; var assemblies = _cachedDependencies.AddOrUpdate(m, newassembly, (key, existingSet) => { lock (existingSet) { existingSet.Add(dependencies.CallingAssembly); } return existingSet; }); } } catch (InvalidPEAssemblyException) { // This often indicates a non-PE file _assembliesWithError.Add(file.Name); } catch (BadImageFormatException) { // This often indicates a PE file with invalid contents (either because the assembly is protected or corrupted) _assembliesWithError.Add(file.Name); } }); // Clear out unresolved dependencies that were resolved during processing ICollection<string> collection; foreach (var assembly in _userAssemblies) { _unresolvedAssemblies.TryRemove(assembly.AssemblyIdentity, out collection); } }
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); }