/// <summary> /// Constructor. /// </summary> /// <param name="syntaxNode">SyntaxNode</param> /// <param name="node">IControlFlowNode</param> /// <param name="summary">MethodSummary</param> private Statement(SyntaxNode syntaxNode, IControlFlowNode node, MethodSummary summary) { this.SyntaxNode = syntaxNode; this.ControlFlowNode = node; this.Summary = summary; }
/// <summary> /// Constructs the data-flow graph node from the specified control-flow graph node. /// </summary> private void Construct(IControlFlowNode cfgNode, DataFlowNode previous, Dictionary <IControlFlowNode, DataFlowNode> visited) { visited.Add(cfgNode, this); if (cfgNode.Statements.Count > 0) { this.Statement = cfgNode.Statements[0]; } previous = this; for (int idx = 1; idx < cfgNode.Statements.Count; idx++) { var nextNode = new DataFlowNode(this.Graph, cfgNode, this.Summary); nextNode.Statement = cfgNode.Statements[idx]; previous.ISuccessors.Add(nextNode); nextNode.IPredecessors.Add(previous); previous = nextNode; } foreach (var successor in cfgNode.ISuccessors) { if (visited.ContainsKey(successor)) { previous.ISuccessors.Add(visited[successor]); visited[successor].IPredecessors.Add(previous); continue; } var nextNode = new DataFlowNode(this.Graph, successor, this.Summary); nextNode.Construct(successor, previous, visited); previous.ISuccessors.Add(nextNode); nextNode.IPredecessors.Add(previous); } }
/// <summary> /// Analyzes the ownership of the given-up symbol /// in the control-flow graph. /// </summary> /// <param name="givenUpSymbol">GivenUpOwnershipSymbol</param> /// <param name="machine">StateMachine</param> /// <param name="model">SemanticModel</param> /// <param name="trace">TraceInfo</param> protected override void AnalyzeOwnershipInControlFlowGraph(GivenUpOwnershipSymbol givenUpSymbol, StateMachine machine, SemanticModel model, TraceInfo trace) { var queue = new Queue <IControlFlowNode>(); queue.Enqueue(givenUpSymbol.Statement.ControlFlowNode); var visitedNodes = new HashSet <IControlFlowNode>(); visitedNodes.Add(givenUpSymbol.Statement.ControlFlowNode); bool repeatGivesUpNode = false; while (queue.Count > 0) { IControlFlowNode node = queue.Dequeue(); var statements = new List <Statement>(); if (!repeatGivesUpNode && node.Equals(givenUpSymbol.Statement.ControlFlowNode)) { statements.AddRange(node.Statements.SkipWhile( val => !val.Equals(givenUpSymbol.Statement))); } else if (repeatGivesUpNode && node.Equals(givenUpSymbol.Statement.ControlFlowNode)) { statements.AddRange(node.Statements.TakeWhile( val => !val.Equals(givenUpSymbol.Statement))); statements.Add(givenUpSymbol.Statement); } else { statements.AddRange(node.Statements); } foreach (var statement in statements) { base.AnalyzeOwnershipInStatement(givenUpSymbol, statement, machine, model, trace); } foreach (var successor in node.ISuccessors) { if (!repeatGivesUpNode && successor.Equals(givenUpSymbol.Statement.ControlFlowNode)) { repeatGivesUpNode = true; visitedNodes.Remove(givenUpSymbol.Statement.ControlFlowNode); } if (!visitedNodes.Contains(successor)) { queue.Enqueue(successor); visitedNodes.Add(successor); } } } }
/// <summary> /// Initializes a new instance of the <see cref="DataFlowNode"/> class. /// </summary> internal DataFlowNode(IGraph <IDataFlowNode> dfg, IControlFlowNode cfgNode, MethodSummary summary) { this.Id = dfg.Nodes.Count; this.Graph = dfg; this.ControlFlowNode = cfgNode; this.Summary = summary; this.ISuccessors = new HashSet <IDataFlowNode>(); this.IPredecessors = new HashSet <IDataFlowNode>(); dfg.Nodes.Add(this); this.DataFlowInfo = new DataFlowInfo(this, summary.AnalysisContext); this.MethodSummaryCache = new Dictionary <ISymbol, ISet <MethodSummary> >(); this.GivesUpOwnershipMap = new HashSet <ISymbol>(); }
/// <summary> /// Checks the node is a predecessor of the specified node. /// </summary> /// <param name="node">INode</param> /// <returns>Boolean</returns> public bool IsPredecessorOf(IControlFlowNode node) { return(this.Graph.IsPredecessorOf(this, node)); }
/// <summary> /// Creates a new statement. /// </summary> /// <param name="syntaxNode">SyntaxNode</param> /// <param name="node">IControlFlowNode</param> /// <param name="summary">MethodSummary</param> /// <returns>Statement</returns> public static Statement Create(SyntaxNode syntaxNode, IControlFlowNode node, MethodSummary summary) { return new Statement(syntaxNode, node, summary); }
/// <summary> /// Checks if the statement is in the same method as /// the specified control-flow graph node. /// </summary> /// <param name="node">IControlFlowNode</param> /// <returns>Boolean</returns> public bool IsInSameMethodAs(IControlFlowNode node) { return this.Summary.Id == node.Summary.Id; }
/// <summary> /// Checks if the statement is in the same method as /// the specified control-flow graph node. /// </summary> /// <param name="node">IControlFlowNode</param> /// <returns>Boolean</returns> public bool IsInSameMethodAs(IControlFlowNode node) { return(this.Summary.Id == node.Summary.Id); }
/// <summary> /// Creates a new statement. /// </summary> /// <param name="syntaxNode">SyntaxNode</param> /// <param name="node">IControlFlowNode</param> /// <param name="summary">MethodSummary</param> /// <returns>Statement</returns> public static Statement Create(SyntaxNode syntaxNode, IControlFlowNode node, MethodSummary summary) { return(new Statement(syntaxNode, node, summary)); }