1 // Licensed to the .NET Foundation under one or more agreements. 2 // The .NET Foundation licenses this file to you under the MIT license. 3 // See the LICENSE file in the project root for more information. 4 5 using System; 6 using System.Collections.Generic; 7 using System.Collections.Immutable; 8 using System.IO; 9 10 namespace ILCompiler.DependencyAnalysisFramework 11 { 12 /// <summary> 13 /// Api for dependency analyzer. The expected use pattern is that a set of nodes will be added to the 14 /// graph as roots. These nodes will internally implement the various dependency details 15 /// so that if MarkedNodeList is called, it can produce the complete graph. For the case 16 /// where nodes have deferred computation the ComputeDependencyRoutine even will be triggered 17 /// to fill in data. 18 /// 19 /// The Log visitor logic can be called at any time, and should log the current set of marked 20 /// nodes and edges in the analysis. (Notably, if its called before MarkedNodeList is evaluated 21 /// it will contain only roots, if its called during, the edges/nodes may be incomplete, and 22 /// if called after MarkedNodeList is computed it will be a complete graph. 23 /// 24 /// </summary> 25 /// <typeparam name="DependencyContextType"></typeparam> 26 public abstract class DependencyAnalyzerBase<DependencyContextType> 27 { 28 /// <summary> 29 /// Add a root node 30 /// </summary> AddRoot(DependencyNodeCore<DependencyContextType> rootNode, string reason)31 public abstract void AddRoot(DependencyNodeCore<DependencyContextType> rootNode, string reason); 32 33 /// <summary> 34 /// Add a root node 35 /// </summary> AddRoot(object rootNode, string reason)36 public void AddRoot(object rootNode, string reason) 37 { 38 AddRoot((DependencyNodeCore<DependencyContextType>)rootNode, reason); 39 } 40 41 /// <summary> 42 /// Return the marked node list. Do not modify this list, as it will cause unexpected behavior. 43 /// Call <see cref="ComputeMarkedNodes"/> to compute the list first. 44 /// </summary> 45 public abstract ImmutableArray<DependencyNodeCore<DependencyContextType>> MarkedNodeList 46 { 47 get; 48 } 49 50 /// <summary> 51 /// Computes the list of marked nodes. This is a no-op if the marked nodes are already computed. 52 /// The list is available as <see cref="MarkedNodeList"/>. 53 /// </summary> ComputeMarkedNodes()54 public abstract void ComputeMarkedNodes(); 55 56 /// <summary> 57 /// This event is triggered when a node is added to the graph. 58 /// </summary> 59 public abstract event Action<DependencyNodeCore<DependencyContextType>> NewMarkedNode; 60 61 /// <summary> 62 /// This event is triggered when the algorithm requires that dependencies of some set of 63 /// nodes be computed. 64 /// </summary> 65 66 public abstract event Action<List<DependencyNodeCore<DependencyContextType>>> ComputeDependencyRoutine; 67 68 /// <summary> 69 /// Used to walk all nodes that should be emitted to a log. Not intended for other purposes. 70 /// </summary> 71 /// <param name="logNodeVisitor"></param> VisitLogNodes(IDependencyAnalyzerLogNodeVisitor<DependencyContextType> logNodeVisitor)72 public abstract void VisitLogNodes(IDependencyAnalyzerLogNodeVisitor<DependencyContextType> logNodeVisitor); 73 74 /// <summary> 75 /// Used to walk the logical edges in the graph as part of log building. 76 /// </summary> 77 /// <param name="logEdgeVisitor"></param> VisitLogEdges(IDependencyAnalyzerLogEdgeVisitor<DependencyContextType> logEdgeVisitor)78 public abstract void VisitLogEdges(IDependencyAnalyzerLogEdgeVisitor<DependencyContextType> logEdgeVisitor); 79 } 80 } 81