Class: Taski::StaticAnalysis::DependencyGraph
- Inherits:
-
Object
- Object
- Taski::StaticAnalysis::DependencyGraph
- Includes:
- TSort
- Defined in:
- lib/taski/static_analysis/dependency_graph.rb
Overview
Builds a complete dependency graph from a root task class and provides topological sorting with cycle detection.
Instance Method Summary collapse
-
#all_tasks ⇒ Array<Class>
Get all task classes in the graph.
-
#build_from(root_task_class) ⇒ DependencyGraph
Build dependency graph starting from root task class using static analysis.
-
#build_from_cached(root_task_class) ⇒ DependencyGraph
Build dependency graph using cached_dependencies (runtime) instead of AST analysis.
-
#cyclic? ⇒ Boolean
Check if the graph contains circular dependencies.
-
#cyclic_components ⇒ Array<Array<Class>>
Get task classes involved in cycles.
-
#dependencies_for(task_class) ⇒ Set<Class>
Get direct dependencies for a task class.
-
#initialize ⇒ DependencyGraph
constructor
A new instance of DependencyGraph.
-
#sorted ⇒ Array<Class>
Get topologically sorted task classes (dependencies first).
-
#strongly_connected_components ⇒ Array<Array<Class>>
Get strongly connected components (useful for debugging cycles).
-
#tsort_each_child(node, &block) ⇒ Object
TSort interface: iterate over children (dependencies) of a node.
-
#tsort_each_node(&block) ⇒ Object
TSort interface: iterate over all nodes.
Constructor Details
#initialize ⇒ DependencyGraph
Returns a new instance of DependencyGraph.
12 13 14 |
# File 'lib/taski/static_analysis/dependency_graph.rb', line 12 def initialize @graph = {} end |
Instance Method Details
#all_tasks ⇒ Array<Class>
Get all task classes in the graph
62 63 64 |
# File 'lib/taski/static_analysis/dependency_graph.rb', line 62 def all_tasks @graph.keys end |
#build_from(root_task_class) ⇒ DependencyGraph
Build dependency graph starting from root task class using static analysis
19 20 21 22 |
# File 'lib/taski/static_analysis/dependency_graph.rb', line 19 def build_from(root_task_class) collect_dependencies(root_task_class) self end |
#build_from_cached(root_task_class) ⇒ DependencyGraph
Build dependency graph using cached_dependencies (runtime) instead of AST analysis
27 28 29 30 |
# File 'lib/taski/static_analysis/dependency_graph.rb', line 27 def build_from_cached(root_task_class) collect_cached_dependencies(root_task_class) self end |
#cyclic? ⇒ Boolean
Check if the graph contains circular dependencies
41 42 43 44 45 46 |
# File 'lib/taski/static_analysis/dependency_graph.rb', line 41 def cyclic? tsort false rescue TSort::Cyclic true end |
#cyclic_components ⇒ Array<Array<Class>>
Get task classes involved in cycles
56 57 58 |
# File 'lib/taski/static_analysis/dependency_graph.rb', line 56 def cyclic_components strongly_connected_components.select { |component| component.size > 1 } end |
#dependencies_for(task_class) ⇒ Set<Class>
Get direct dependencies for a task class
69 70 71 |
# File 'lib/taski/static_analysis/dependency_graph.rb', line 69 def dependencies_for(task_class) @graph.fetch(task_class, Set.new) end |
#sorted ⇒ Array<Class>
Get topologically sorted task classes (dependencies first)
35 36 37 |
# File 'lib/taski/static_analysis/dependency_graph.rb', line 35 def sorted tsort end |
#strongly_connected_components ⇒ Array<Array<Class>>
Get strongly connected components (useful for debugging cycles)
50 51 52 |
# File 'lib/taski/static_analysis/dependency_graph.rb', line 50 def strongly_connected_components each_strongly_connected_component.to_a end |
#tsort_each_child(node, &block) ⇒ Object
TSort interface: iterate over children (dependencies) of a node
79 80 81 |
# File 'lib/taski/static_analysis/dependency_graph.rb', line 79 def tsort_each_child(node, &block) @graph.fetch(node, Set.new).each(&block) end |
#tsort_each_node(&block) ⇒ Object
TSort interface: iterate over all nodes
74 75 76 |
# File 'lib/taski/static_analysis/dependency_graph.rb', line 74 def tsort_each_node(&block) @graph.each_key(&block) end |