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); }
private void GetEfferentGraph(string parent, string fullName, IDictionary <string, bool> cutOffs, List <ChangeContext> found, AffectedGraph graph, bool isRootNode, TypeDefinition originalContext) { var entry = _cache.TryGetEfferentCouplingNode(fullName); var afferent = _cache.TryGetAfferentCouplingNode(fullName); if (isRootNode) { entry = entry ?? afferent; found.Add(new ChangeContext(fullName, null)); graph.AddNode(GetGraphNode(fullName, entry, true, true)); if (entry != null && entry.MemberReference != null) { var refer = entry.MemberReference as MethodReference; if (refer != null && _testStrategies.IsTest(refer)) { return; } } } //TODO Greg this hamstrings some stuff but should work better in most cases //I think we only really need statics past here but need to look it over a bit. return; WriteWalkerDebug("checking " + fullName, 0); if (entry == null) { WriteWalkerDebug("efferent entry is null", 0); if (afferent != null && afferent.MemberReference is MethodReference) { return; //Leaf node to a method call } } if (afferent == null) { WriteWalkerDebug("afferent entry is null", 0); } if (afferent != null) { var memref = afferent.MemberReference as MethodReference; MethodDefinition def = null; if (memref != null) { def = memref.ThreadSafeResolve(); } if (!isRootNode && def != null) { if (def.IsGetter) { return; } if (def.DeclaringType.IsInterface) { return; //don't recurse forward on interface calls } if (!def.HasThis) { return; } } var reference = afferent.MemberReference as FieldReference; //Leaf node to a field reference if (reference != null) { graph.AddNode(GetGraphNode(fullName, afferent, isRootNode, false)); if (parent != null) { graph.AddConnection(parent, fullName, true); } found.Add(new ChangeContext(fullName, originalContext)); } } if (entry == null) { return; } graph.AddNode(GetGraphNode(fullName, entry, isRootNode, false)); if (parent != null) { graph.AddConnection(parent, fullName, true); } foreach (var current in entry.Couplings) { if (cutOffs.ContainsKey(current.To)) { continue; } if (current.IgnoreWalk) { continue; } if (current.ActualReference is MethodReference && !current.IsSelfCall) { continue; } cutOffs.Add(current.To, true); GetEfferentGraph(fullName, current.To, cutOffs, found, graph, false, originalContext); } }