public IList <AssignmentTree> PerformBacktrackingSearch(string startingObjectKey, ISourceDetector nameSourceDetector, List <GoToInstancePattern> permittedToGoInstancePatterns, List <string> searchBaseConstructorPatterns) { _goToInstancePatterns = permittedToGoInstancePatterns; _searchBaseConstructorPatterns = searchBaseConstructorPatterns; var assignmentTrees = new List <AssignmentTree>(); CreateStartTraceSection(startingObjectKey); var startingKeys = _tripleStore.GetTo(startingObjectKey); foreach (var start in startingKeys) { Print(startingObjectKey, 0); var exploreTreeNode = new ExploreTreeNode() { FullSignature = start.ToString() }; var rootNode = new AssignmentTreeNode(start); var assignmentTree = new AssignmentTree(); assignmentTree.RootNode = rootNode; var counter = new BacktrackCounter(); _instructionKeyStack = new Stack <string>(); BacktrackingSearch(start, start, nameSourceDetector, counter, assignmentTree, rootNode, false, exploreTreeNode, 0); assignmentTrees.Add(assignmentTree); } return(assignmentTrees); }
private BacktrackResult GoToInstance(Triple startTriple, Triple triple, ISourceDetector nameSourceDetector, AssignmentTree assignmentTree, AssignmentTreeNode lastNode, BacktrackCounter counter, bool inReturnScope, ExploreTreeNode exploreTreeNode, int depth) { var branchResult = BacktrackingSearchFromInstance(startTriple, triple, nameSourceDetector, assignmentTree, lastNode, counter, inReturnScope, exploreTreeNode, depth); if (branchResult != BacktrackResult.BranchFailure) { return(branchResult); } branchResult = BacktrackingSearchFromInstanceProperty(startTriple, triple, nameSourceDetector, assignmentTree, lastNode, counter, inReturnScope, exploreTreeNode, depth); if (branchResult != BacktrackResult.BranchFailure) { return(branchResult); } return(BacktrackResult.BranchFailure); }
private BacktrackResult GoToBaseConstructor(Triple startTriple, Triple triple, ISourceDetector nameSourceDetector, AssignmentTree assignmentTree, AssignmentTreeNode lastNode, BacktrackCounter counter, bool inReturnScope, ExploreTreeNode exploreTreeNode, int depth) { var baseClass = triple.To.InheritsFromConcreteClass; var baseClassCtors = _tripleStore.GetAllTriples().Where(x => x.To.ObjectKey.IndexOf(baseClass) > -1 && x.To.ObjectKey.IndexOf(".ctor") > -1); foreach (var baseClassCtorTriple in baseClassCtors) { if (baseClassCtorTriple.To.InstanceOwnerKey.Equals(triple.To.MemberName)) { var childExploreTreeNode = CreateExploreTreeNode(baseClassCtorTriple, "ViaBaseConstructor", exploreTreeNode); var branchResult = BacktrackingSearchMatches(startTriple, triple, new List <Triple>() { baseClassCtorTriple }, nameSourceDetector, assignmentTree, lastNode, counter, inReturnScope, true, childExploreTreeNode, depth); if (branchResult != BacktrackResult.BranchFailure) { return(branchResult); } } } return(BacktrackResult.BranchFailure); }
private void AddTargetToAssignmentTree(Triple triple, AssignmentTree assignmentTree, AssignmentTreeNode lastNode, int depth) { Print("FOUND " + triple.From.ObjectKey, depth); var foundAssignmentTreeNode = new AssignmentTreeNode(triple, true); lastNode.Children.Add(foundAssignmentTreeNode); assignmentTree.FoundNodes.Add(foundAssignmentTreeNode); }
private BacktrackResult BacktrackingSearchFromInstructionKeyStack(Triple startTriple, Triple triple, ISourceDetector nameSourceDetector, AssignmentTree assignmentTree, AssignmentTreeNode lastNode, BacktrackCounter counter, bool inReturnScope, ExploreTreeNode exploreTreeNode, int depth) { var result = BacktrackResult.BranchFailure; if (_instructionKeyStack.Count == 0) { // TODO log error Print("Tried to pop empty stack " + triple, depth); return(BacktrackResult.Stop); } var instructionKey = _instructionKeyStack.Pop(); Print("Pop from instruction stack " + instructionKey, depth); var matchingTriples = _tripleStore.GetToViaInstructionKey(instructionKey); List <Triple> targetTriples = null; if (triple.From.ObjectKey.EndsWith("return")) { targetTriples = matchingTriples; } else { var targetPosition = triple.From.ObjectKey.Substring(triple.From.ObjectKey.IndexOf(">>") + 2); targetTriples = matchingTriples.Where(x => x.To.ObjectKey.EndsWith(targetPosition)).ToList(); } if (targetTriples.Any()) { var branchResult = BacktrackingSearchMatches(startTriple, triple, targetTriples, nameSourceDetector, assignmentTree, lastNode, counter, inReturnScope, true, exploreTreeNode, depth); if (branchResult == BacktrackResult.Success) { result = BacktrackResult.Success; } else if (branchResult == BacktrackResult.Stop) { return(branchResult); } } return(result); }
private BacktrackResult BacktrackingSearchFromInstanceProperty(Triple startTriple, Triple triple, ISourceDetector nameSourceDetector, AssignmentTree assignmentTree, AssignmentTreeNode lastNode, BacktrackCounter counter, bool inReturnScope, ExploreTreeNode exploreTreeNode, int depth) { Print("Check for instance property assignments", depth); var result = BacktrackResult.BranchFailure; var instanceMemberAssignments = _tripleStore.GetToViaInstanceOwnerKey(triple.To.InstanceOwnerKey); if (instanceMemberAssignments.Any()) { if (instanceMemberAssignments.Count() > 1 && instanceMemberAssignments.Any(x => x.ParentAssembly.Equals(triple.ParentAssembly))) { instanceMemberAssignments = instanceMemberAssignments.Where(x => x.ParentAssembly.Equals(triple.ParentAssembly)).ToList(); } foreach (var instanceAssignment in instanceMemberAssignments) { if (instanceAssignment.To.ObjectKey.Equals(startTriple.To.ObjectKey)) { continue; } var childExploreTreeNode = CreateExploreTreeNode(instanceAssignment, "InstanceMemberAssignment", exploreTreeNode); var assignmentNode = new AssignmentTreeNode(instanceAssignment); assignmentNode.IsRegressionToInstance = true; Print("Gone to instance property assignment " + instanceAssignment, depth); var branchResult = BacktrackingSearch(startTriple, instanceAssignment, nameSourceDetector, counter, assignmentTree, assignmentNode, inReturnScope, childExploreTreeNode, depth); if (branchResult == BacktrackResult.Success) { lastNode.Children.Add(assignmentNode); result = BacktrackResult.Success; } else if (branchResult == BacktrackResult.Stop) { return(branchResult); } } } return(result); }
private BacktrackResult BacktrackingSearchFromInstance(Triple startTriple, Triple triple, ISourceDetector nameSourceDetector, AssignmentTree assignmentTree, AssignmentTreeNode lastNode, BacktrackCounter counter, bool inReturnScope, ExploreTreeNode exploreTreeNode, int depth) { Print("Check for instance assignments", depth); var result = BacktrackResult.BranchFailure; if (triple.To.InstanceOwnerKey == null) { return(result); } List <Triple> instanceAssignments = _tripleStore.GetTo(triple.To.InstanceOwnerKey); Print(instanceAssignments.Count + " Instance Assignments", depth); if (instanceAssignments.Any()) { int instanceCounter = 0; foreach (var instanceAssignment in instanceAssignments) { instanceCounter++; var childExploreTreeNode = CreateExploreTreeNode(instanceAssignment, "InstanceAssignment", exploreTreeNode); var assignmentNode = new AssignmentTreeNode(instanceAssignment); assignmentNode.IsRegressionToInstance = true; Print("Gone to instance assignment " + instanceCounter + ": " + instanceAssignment, depth); var branchResult = BacktrackingSearch(startTriple, instanceAssignment, nameSourceDetector, counter, assignmentTree, assignmentNode, inReturnScope, childExploreTreeNode, depth); if (branchResult == BacktrackResult.Success) { lastNode.Children.Add(assignmentNode); result = BacktrackResult.Success; } else if (branchResult == BacktrackResult.Stop) { return(branchResult); } } } return(result); }
private BacktrackResult BacktrackingSearchMatches(Triple startTriple, Triple triple, List <Triple> targetMatchingTriples, ISourceDetector nameSourceDetector, AssignmentTree assignmentTree, AssignmentTreeNode lastNode, BacktrackCounter counter, bool inReturnScope, bool printObjectKey, ExploreTreeNode exploreTreeNode, int depth) { var result = BacktrackResult.BranchFailure; int matchCounter = 0; foreach (var backTriple in targetMatchingTriples) { matchCounter++; ExploreTreeNode childExploreTreeNode = null; if (printObjectKey) { childExploreTreeNode = CreateExploreTreeNode(backTriple, "ObjectKey", exploreTreeNode); Print(matchCounter + " matched object key " + backTriple, depth); } else { childExploreTreeNode = CreateExploreTreeNode(backTriple, "InstructionKey", exploreTreeNode); Print(matchCounter + " MATCH INSTRUCTION KEY " + triple.From.InstructionKey, depth); } var assignmentNode = new AssignmentTreeNode(backTriple); var branchResult = BacktrackingSearch(startTriple, backTriple, nameSourceDetector, counter, assignmentTree, assignmentNode, inReturnScope, childExploreTreeNode, depth); if (branchResult == BacktrackResult.Success) { lastNode.Children.Add(assignmentNode); result = BacktrackResult.Success; } else if (branchResult == BacktrackResult.Stop) { return(branchResult); } } return(result); }
private BacktrackResult BacktrackingSearch(Triple startTriple, Triple triple, ISourceDetector nameSourceDetector, BacktrackCounter counter, AssignmentTree assignmentTree, AssignmentTreeNode lastNode, bool inReturnScope, ExploreTreeNode exploreTreeNode, int depth) { depth++; counter.Count++; Print("BACKTRACKED TO " + triple, depth); if (IsRecursiveLoop(exploreTreeNode)) { Print("RECURSIVE LOOP", depth); return(BacktrackResult.BranchFailure); } if (counter.Count > 150) { Print("Limit Reached", depth); return(BacktrackResult.Stop); } if (IsAssignedByMethod(triple)) { var canStepInto = _tripleStore.Back(triple).Any(); var methodRef = (MethodReference)triple.From.Instruction.Operand; if (methodRef.HasParameters && canStepInto) { PushInstructionKeyToStack(triple, depth); inReturnScope = true; } } if (nameSourceDetector.IsNameSource(triple)) { AddTargetToAssignmentTree(triple, assignmentTree, lastNode, depth); return(BacktrackResult.Success); } if (IsReturnScopeArgument(triple, ref inReturnScope)) { var branchResult = BacktrackingSearchFromInstructionKeyStack(startTriple, triple, nameSourceDetector, assignmentTree, lastNode, counter, inReturnScope, exploreTreeNode, depth); if (branchResult != BacktrackResult.BranchFailure) { return(branchResult); } } else if (ShouldGoToBaseConstructor(triple)) { var branchResult = GoToBaseConstructor(startTriple, triple, nameSourceDetector, assignmentTree, lastNode, counter, inReturnScope, exploreTreeNode, depth); if (branchResult != BacktrackResult.BranchFailure) { return(branchResult); } } else if (ShouldOnlyGoToInstance(triple)) { var branchResult = GoToInstance(startTriple, triple, nameSourceDetector, assignmentTree, lastNode, counter, inReturnScope, exploreTreeNode, depth); if (branchResult != BacktrackResult.BranchFailure) { return(branchResult); } } else { if (FromIsRelevantObjectInitializerConstructor(triple)) { Print("Is Relevant Object Initializer Constructor" + triple, depth); var objectInitializerMemberTriples = _tripleStore.GetToViaContructorInstructionKey(triple.From.InstructionKey); if (objectInitializerMemberTriples.Any()) { Print("Found " + objectInitializerMemberTriples.Count + " Object Initializer Members " + triple, depth); var branchResult = BacktrackingSearchMatches(startTriple, triple, objectInitializerMemberTriples, nameSourceDetector, assignmentTree, lastNode, counter, inReturnScope, true, exploreTreeNode, depth); if (branchResult != BacktrackResult.BranchFailure) { return(branchResult); } } } var goneToInstance = false; if (ShouldGoToInstanceFirst(triple)) { goneToInstance = true; var branchResult = GoToInstance(startTriple, triple, nameSourceDetector, assignmentTree, lastNode, counter, inReturnScope, exploreTreeNode, depth); if (branchResult != BacktrackResult.BranchFailure) { return(branchResult); } } Print("Check for direct triple to -> from match" + triple, depth); var backTriples = _tripleStore.Back(triple); if (backTriples.Any()) { var branchResult = BacktrackingSearchMatches(startTriple, triple, backTriples, nameSourceDetector, assignmentTree, lastNode, counter, inReturnScope, true, exploreTreeNode, depth); if (branchResult != BacktrackResult.BranchFailure) { return(branchResult); } } if (triple.From.ObjectType == ObjectType.Method) { Print("Step over method to argument " + triple, depth); PushInstructionKeyToStack(triple, depth); var branchResult = BacktrackingSearchFromInstructionKeyStack(startTriple, triple, nameSourceDetector, assignmentTree, lastNode, counter, inReturnScope, exploreTreeNode, depth); if (branchResult != BacktrackResult.BranchFailure) { return(branchResult); } } if (CanGoToInstance(triple) && !goneToInstance) { var branchResult = GoToInstance(startTriple, triple, nameSourceDetector, assignmentTree, lastNode, counter, inReturnScope, exploreTreeNode, depth); if (branchResult != BacktrackResult.BranchFailure) { return(branchResult); } } } Print("DEADEND", depth); return(BacktrackResult.BranchFailure); }