Esempio n. 1
0
        // TODO: Do it incrementally
        // TODO: Heap
        internal void Update(StatementFlowView nextStatement)
        {
            if (nextStatement == this.nextStatement)
            {
                return;
            }

            this.Variables.Clear();

            this.nextStatement = nextStatement;
            if (this.nextStatement == null)
            {
                this.heapVersion = 0;
                return;
            }

            this.heapVersion = this.nextStatement.MethodFlowView.StartHeapVersion;

            var varMap = new Dictionary <string, VariableReplayView>();

            foreach (var statement in this.nextStatement.MethodFlowView.StatementFlows)
            {
                if (statement == this.nextStatement)
                {
                    break;
                }

                if (statement.DisplayRecord.VariableName is string varName)
                {
                    if (!varMap.TryGetValue(varName, out var varView))
                    {
                        varView = new VariableReplayView(
                            varName,
                            statement.Value,
                            statement.Type,
                            statement.HeapLocation);
                        varMap.Add(varName, varView);
                        this.Variables.Add(varView);
                    }

                    varView.Value        = statement.Value;
                    varView.Type         = statement.Type;
                    varView.HeapLocation = statement.HeapLocation;
                }

                if (statement.HeapLocation?.HeapVersion > this.heapVersion)
                {
                    this.heapVersion = statement.HeapLocation.Value.HeapVersion;
                }
                else if (statement.CalledMethod?.EndHeapVersion > this.heapVersion)
                {
                    this.heapVersion = statement.CalledMethod.EndHeapVersion;
                }
            }

            this.heap.Redraw();
        }
Esempio n. 2
0
        private void UpdateToolSelectedStatement(StatementFlowView statement)
        {
            // The last assignment will cause calling this.Update(statement)
            this.ToolView.SelectedPath = statement.MethodFlowView.PathView;
            this.ToolView.SelectedPath.SelectedMethodFlow = statement.MethodFlowView;

            if (this.ToolView.SelectedPath.SelectedMethodFlow.SelectedStatementFlow == statement)
            {
                // Force update
                this.ToolView.SelectedPath.SelectedMethodFlow.SelectedStatementFlow = null;
            }

            this.ToolView.SelectedPath.SelectedMethodFlow.SelectedStatementFlow = statement;
        }
Esempio n. 3
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);
            }
        }