Ejemplo n.º 1
0
        private void Initialize()
        {
            this.statementFlows = new List <StatementFlowView>();
            this.callees        = new List <MethodFlowView>();

            var toolView   = this.PathView.ToolView;
            var syntaxTree = this.location.Method.Locations[0].SourceTree;
            var text       = syntaxTree.GetText();
            ////var document = toolView.CurrentSolution.GetDocument(syntaxTree);  // TODO: Consider storing this

            var executionModel = this.PathView.ExecutionModel;
            var flowGraphId    = executionModel.PathNodes[this.startIndex].Graph.Id;
            var displayGraph   = toolView.GraphProvider.GetDisplayGraph(flowGraphId);

            int  heapVersion = this.StartHeapVersion;
            bool endLoop     = false;

            for (int i = this.startIndex; i <= this.endIndex && !endLoop; i++)
            {
                heapVersion = AdvanceHeapVersion(heapVersion, executionModel, i);

                var            flowNode = executionModel.PathNodes[i];
                MethodFlowView callee   = null;

                if (flowNode is CallFlowNode && i != this.endIndex)
                {
                    // Traverse nested method calls
                    callee = this.ProcessCallee(executionModel, i, heapVersion);

                    if (callee.endIndex < this.endIndex)
                    {
                        // Nested call whose result is displayed in the subsequent flow of this method
                        i           = callee.endIndex + 1;
                        heapVersion = callee.EndHeapVersion;
                        Contract.Assert(flowNode == executionModel.PathNodes[i]);
                    }
                    else
                    {
                        // Nested call somewhere in which the execution ends
                        endLoop = true;
                    }
                }

                // Produce statements from display nodes
                this.ProcessStatements(text, displayGraph, executionModel, i, callee);
            }

            Contract.Assert(heapVersion <= this.EndHeapVersion);
        }
Ejemplo n.º 2
0
 internal MethodFlowView(
     PathView pathView,
     MethodFlowView caller,
     MethodLocation location,
     int startIndex,
     int endIndex,
     int startHeapVersion,
     int endHeapVersion)
 {
     this.PathView         = pathView;
     this.Caller           = caller;
     this.location         = location;
     this.startIndex       = startIndex;
     this.endIndex         = endIndex;
     this.StartHeapVersion = startHeapVersion;
     this.EndHeapVersion   = endHeapVersion;
 }
Ejemplo n.º 3
0
        private MethodFlowView AddCallee(int startIndex, int endIndex, int startHeapVersion, int endHeapVersion)
        {
            var toolView       = this.PathView.ToolView;
            var graph          = this.PathView.ExecutionModel.PathNodes[startIndex].Graph;
            var calleeLocation = toolView.GraphProvider.GetLocation(graph.Id);
            var callee         = new MethodFlowView(
                this.PathView,
                this,
                calleeLocation,
                startIndex,
                endIndex,
                startHeapVersion,
                endHeapVersion);

            this.callees.Add(callee);

            return(callee);
        }
Ejemplo n.º 4
0
 internal StatementFlowView(
     MethodFlowView methodFlowView,
     int index,
     DisplayNodeRecord displayRecord,
     string statement,
     string value,
     string type,
     HeapModelLocation?heapLocation = null,
     MethodFlowView calledMethod    = null)
 {
     this.MethodFlowView = methodFlowView;
     this.Index          = index;
     this.DisplayRecord  = displayRecord;
     this.Statement      = statement;
     this.Value          = value;
     this.Type           = type;
     this.HeapLocation   = heapLocation;
     this.CalledMethod   = calledMethod;
 }
Ejemplo n.º 5
0
        private void UpdateSelectedMethod(MethodFlowView previousValue)
        {
            if (previousValue != null)
            {
                previousValue.IsSelected = false;
            }

            if (this.SelectedMethodFlow == null)
            {
                return;
            }

            // Select the appropriate method
            this.SelectedMethodFlow.IsSelected = true;

            // Expand all the methods leading to it in the chain
            var caller = this.SelectedMethodFlow.Caller;

            while (caller != null)
            {
                caller.IsExpanded = true;
                caller            = caller.Caller;
            }
        }
Ejemplo n.º 6
0
        private void ProcessStatements(
            SourceText text,
            DisplayGraph displayGraph,
            ExecutionModel executionModel,
            int nodeIndex,
            MethodFlowView calledMethod = null)
        {
            var  modelManager    = this.PathView.ToolView.GraphProvider.ModelManager;
            var  flowNode        = executionModel.PathNodes[nodeIndex];
            bool isLastInnerNode =
                (nodeIndex == executionModel.PathNodes.Length - 1) &&
                flowNode is InnerFlowNode;
            var nodeInterpretations = executionModel.NodeInterpretations[nodeIndex];
            var heapLocations       = executionModel.HeapLocations[nodeIndex];

            // TODO: Consider optimizing
            // TODO: Group the records by their display nodes
            var displayRecords = new List <DisplayNodeRecord>();

            foreach (var displayNode in displayGraph.Nodes)
            {
                displayRecords.AddRange(displayNode.Records.Where(record => record.FlowNode == flowNode));

                // Temporary: Replace by this if only the last result of a DisplayNode is important
                // (Behaves weirdly in case of methods and their arguments, as they are distributed between
                //  two FlowNodes)
                ////var displayRecord = displayNode.Records.LastOrDefault(record => record.FlowNode == flowNode);
                ////if (displayRecord != null)
                ////{
                ////    displayRecords.Add(displayRecord);
                ////}
            }

            foreach (var displayRecord in displayRecords)
            {
                Contract.Assert(displayRecord != null);
                string            statement    = text.ToString(displayRecord.Span);
                string            value        = null;
                string            type         = null;
                HeapModelLocation?heapLocation = null;
                if (displayRecord.Type != null)
                {
                    var modelFactory = modelManager.TryGetFactory(displayRecord.Type);
                    if (modelFactory.ValueKind == ValueModelKind.Interpretation)
                    {
                        // Hide the remaining portion of the inner CFG node where the exploration started from
                        if (isLastInnerNode && displayRecord.FirstVariableIndex >= nodeInterpretations.Length)
                        {
                            continue;
                        }

                        var sortRequirements = modelFactory.GetExpressionSortRequirements(displayRecord.Type);
                        var interpretations  = nodeInterpretations
                                               .Skip(displayRecord.FirstVariableIndex)
                                               .Take(sortRequirements.Count)
                                               .ToArray();

                        if (interpretations.Length != 0 &&
                            interpretations.All(interpretation => interpretation != null))
                        {
                            var valueModel = modelFactory.GetValueModel(displayRecord.Type, interpretations);

                            value = valueModel.ValueText;
                            type  = displayRecord.Type.Name;
                        }
                    }
                    else
                    {
                        Contract.Assert(modelFactory.ValueKind == ValueModelKind.Reference);

                        bool locationExists = displayRecord.FirstVariableIndex < heapLocations.Length;

                        // Hide the remaining portion of the inner CFG node where the exploration started from
                        if (isLastInnerNode && !locationExists)
                        {
                            continue;
                        }

                        if (locationExists)
                        {
                            heapLocation = heapLocations[displayRecord.FirstVariableIndex];
                            var valueModel = modelFactory.GetValueModel(
                                displayRecord.Type,
                                heapLocation.Value,
                                executionModel.HeapModel);

                            value = valueModel.ValueText;
                            type  = displayRecord.Type.Name;
                        }
                    }
                }

                // Display a call only on the last statement of a call node
                // (In future, display node records concerning argument evaluation might be added)
                var called = (calledMethod != null && displayRecord == displayRecords.Last()) ? calledMethod : null;

                var statementFlow = new StatementFlowView(
                    this,
                    this.statementFlows.Count,
                    displayRecord,
                    !string.IsNullOrEmpty(statement) ? statement : displayRecord.VariableName,
                    value,
                    type,
                    heapLocation,
                    called);
                this.statementFlows.Add(statementFlow);
            }
        }