public AffectedGraph GetCouplingGraphFor(string cacheName) { var affected = new List <ChangeContext>(); var graph = new AffectedGraph(); var forwardCutOffPoints = new Dictionary <string, bool>(); var backCutOffPoints = new Dictionary <string, bool>(); TypeDefinition scope = null; GetEfferentGraph(null, cacheName, forwardCutOffPoints, affected, graph, true, scope); WriteWalkerDebug("got " + affected + " nodes for " + cacheName, 0); var rets = affected.ForkAndJoinTo(_numthreads, x => { FillAfferentGraph(x.Member, backCutOffPoints, graph, null, 0, null, false, new List <string>(), GenericContext.Empty(), false); //gets all tests Ca return(true); }); return(graph); }
private void RecurseAfferentCouplings(string fullName, int depth, Dictionary <string, bool> history, bool inInheritanceChain, TypeDefinition inheritedTypeContext, AffectedGraph graph, MemberReference parent, List <string> breadCrumbs, GenericContext genericContext) { var afferentEntry = _cache.TryGetAfferentCouplingNode(fullName); if (afferentEntry == null) { return; } genericContext.SetIndirectConstraintsOn(afferentEntry.MemberReference, parent, inInheritanceChain); if (!inInheritanceChain && genericContext.IsClear()) { lock (history) //double lock, TryCutPointPrune already did this { if (!history.ContainsKey(fullName)) { history.Add(fullName, true); } } } foreach (var current in afferentEntry.Couplings) { if (current.IgnoreWalk) { continue; } var proposed = genericContext.GetGenericContextOf(current.ActualReference); if (!genericContext.CanTransitionTo(proposed)) { WriteWalkerDebug("Generics truncate", depth); continue; } var newContext = genericContext.TransitionTo(proposed); FillAfferentGraph(current.To, history, graph, afferentEntry.MemberReference, depth + 1, inheritedTypeContext, inInheritanceChain && current.IsSelfCall, breadCrumbs, newContext, current.IsSelfCall); } }
private void RecurseSynonyms(int depth, Dictionary <string, bool> history, TypeDefinition inheritedTypeContext, MethodDefinition currentDefinition, AffectedGraph graph, List <string> breadCrumbs, GenericContext genericContext) { var synonyms = SynonymFinder.FindSynonymsFor(currentDefinition); foreach (var current in synonyms) { var c = current as MethodDefinition; if (c == null) { continue; //shouldn't happen } if (!c.DeclaringType.IsInterface) { FillAfferentGraph(current.GetCacheName(), history, graph, currentDefinition, depth + 1, inheritedTypeContext, true, breadCrumbs, genericContext, true); //always a base } else { FillAfferentGraph(current.GetCacheName(), history, graph, currentDefinition, depth + 1, inheritedTypeContext, false, breadCrumbs, genericContext, false); } } }
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); }