private void AddAfferentCoupling(MemberReference from, IEnumerable<MemberAccess> to) { CouplingCacheNode node; var toFullName = from.GetCacheName(); if (!_afferentCache.TryGetValue(toFullName, out node)) { lock (_afferentCache) { if (!_afferentCache.TryGetValue(toFullName, out node)) { node = new CouplingCacheNode(toFullName, from); _afferentCache.Add(toFullName, node); } } } lock (node) { foreach (var current in to) { node.AddCoupling(new Coupling(current.MemberReference.GetCacheName(), current.IsReadOnly, false, current.IsSelfCall, current.OnField, current.ActualMethodDefinition)); } } }
private void FillAfferentGraph(string fullName, Dictionary<string, bool> cutPoints, AffectedGraph graph, MemberReference parent, int depth, TypeDefinition inheritedTypeContext, bool inVirtual, List<string> breadCrumbs, GenericContext genericContext, bool inSelf) { WriteWalkerDebug(fullName, depth); if (TryBreadCrumbsPrune(fullName, depth, breadCrumbs)) { if (parent != null) { WriteWalkerDebug("truncating but adding connection to " + fullName, depth); graph.AddConnection(parent.GetCacheName(), fullName, false); } return; } breadCrumbs.Add(fullName); if (TryCutPointPrune(fullName, depth, cutPoints)) { if (parent != null) { WriteWalkerDebug("bread crumbs truncating but adding connection to " + fullName, depth); graph.AddConnection(parent.GetCacheName(), fullName, false); } return; } var efferentEntry = _cache.TryGetEfferentCouplingNode(fullName); var afferentEntry = _cache.TryGetEfferentCouplingNode(fullName); MethodDefinition currentDefinition = null; if (efferentEntry != null) { TypeReference parentType = null; if (parent != null) parentType = parent.DeclaringType; var definition = efferentEntry.MemberReference.DeclaringType.ThreadSafeResolve(); if (TryInterfacePrune(fullName, depth, breadCrumbs, efferentEntry, parentType, definition)) return; if (TryInheritancePrune(fullName, depth, breadCrumbs, inVirtual, definition, inheritedTypeContext)) {return;} inheritedTypeContext = GetNewTypeContext(inheritedTypeContext, definition); currentDefinition = efferentEntry.MemberReference as MethodDefinition; if (currentDefinition != null) { if(currentDefinition.DeclaringType == null) {} if (parent is FieldReference && currentDefinition.IsConstructor) { breadCrumbs.Remove(fullName); return; } } } var touse = afferentEntry ?? efferentEntry; WriteWalkerDebug("adding node " + fullName, depth); var newnode = GetGraphNode(fullName, touse, parent == null, false); graph.AddNode(newnode); if (parent != null) { graph.AddConnection(parent.GetCacheName(), newnode.FullName, false); } if(currentDefinition != null) RecurseSynonyms(depth, cutPoints, inheritedTypeContext, currentDefinition, graph, breadCrumbs, genericContext); RecurseAfferentCouplings(fullName, depth, cutPoints, inVirtual, inheritedTypeContext, graph, parent, breadCrumbs, genericContext); breadCrumbs.Remove(fullName); }