Ejemplo n.º 1
0
        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);
        }