private IngoingEdgesOverlay ComputeIngoingEdges(BuildGraph graph) { var ingoing = new IngoingEdgesOverlay(() => new List <EdgeInfo>()); var visited = new OrdinalOverlay <BuildNodeId, BuildNode, bool>(); var stack = new Stack <BuildNode>(); stack.Push(graph.EnterNode); visited[graph.EnterNode] = true; while (stack.Count > 0) { var node = stack.Pop(); foreach (var edge in node.OutgoingEdges) { var edgeInfo = new EdgeInfo(edge, node); ingoing[edge.To].Add(edgeInfo); if (!visited[edge.To]) { stack.Push(edge.To); visited[edge.To] = true; } } } return(ingoing); }
public BuildingContext(CSharpGraphBuilder builder, BuildGraph graph) { Contract.Requires(builder != null); Contract.Requires(graph != null); this.builder = builder; this.Graph = graph; }
public async Task <BuildGraph> BuildAsync(GraphDepth depth = GraphDepth.Value) { this.readyQueue.Clear(); this.pending.Clear(); var graph = new BuildGraph(this.documentId, this.methodSyntax); this.readyQueue.Enqueue(graph.EnterNode); var context = new BuildingContext(this, graph); var visitor = CreateVisitor(context, depth); while (this.readyQueue.Count > 0 || this.pending.Count > 0) { if (this.readyQueue.Count > 0) { var node = this.readyQueue.Dequeue(); Contract.Assert(context.PendingTask == null); context.CurrentNode = node; visitor.Visit(node.Syntax); if (context.PendingTask != null) { this.pending.Add(context); // Create new visitor and context so that CurrentNode is not changed when awaited context = new BuildingContext(this, graph); visitor = CreateVisitor(context, depth); } } else if (this.pending.Count > 0) { // TODO: Consider making this more effective // (e.g. directly access and remove the particular node) await Task.WhenAny(this.pending.Select(item => item.PendingTask)); this.pending.RemoveWhere(item => item.PendingTask.IsCompleted); } // TODO: Handle the exceptions thrown in the tasks, if necessary } return(graph); }
public FlowGraphTranslator(BuildGraph buildGraph, DisplayGraph displayGraph, FlowGraphId flowGraphId) { this.BuildGraph = buildGraph; this.DisplayGraph = displayGraph; this.flowGraphId = flowGraphId; }