Class: LiveCable::Rendering::MethodAnalyzer

Inherits:
Object
  • Object
show all
Defined in:
lib/live_cable/rendering/method_analyzer.rb

Overview

Analyzes component methods to track their dependencies on reactive variables and other methods, enabling fine-grained change tracking

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(component_class) ⇒ MethodAnalyzer

Returns a new instance of MethodAnalyzer.



11
12
13
14
15
# File 'lib/live_cable/rendering/method_analyzer.rb', line 11

def initialize(component_class)
  @component_class = component_class
  @dependencies = {}
  @analyzed = false
end

Instance Attribute Details

#dependenciesHash (readonly)

Returns:

  • (Hash)


9
10
11
# File 'lib/live_cable/rendering/method_analyzer.rb', line 9

def dependencies
  @dependencies
end

Instance Method Details

#analyze_all_methodsHash

Analyze all methods in the component and build dependency graph

Returns:

  • (Hash)

    { method_name => { methods: Set, reactive_vars: Set } }



19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/live_cable/rendering/method_analyzer.rb', line 19

def analyze_all_methods
  return dependencies if analyzed

  # Get the source file for this component
  source_location = Object.const_source_location(component_class.name)

  file_path = source_location[0]
  return {} unless File.exist?(file_path)

  # Parse the entire file once
  source_code = File.read(file_path)
  parsed = Prism.parse(source_code)

  # Collect all method definitions in one pass
  collector = MethodCollector.new(component_class)
  collector.visit(parsed.value)

  @dependencies = collector.dependencies
  @analyzed = true
  dependencies
end

#analyze_method(method_name) ⇒ Hash?

Get dependencies for a specific method (analyzes all if not done yet)

Parameters:

  • method_name (Symbol)

    The method name

Returns:

  • (Hash, nil)

    { methods: Set, reactive_vars: Set }



44
45
46
47
# File 'lib/live_cable/rendering/method_analyzer.rb', line 44

def analyze_method(method_name)
  analyze_all_methods unless analyzed
  dependencies[method_name]
end

#expanded_dependencies(method_name) ⇒ Set

Get the expanded/transitive dependencies for a method. Results are cached permanently since method definitions don't change at runtime.

Parameters:

  • method_name (Symbol)

    The method to expand

Returns:

  • (Set)

    Set of reactive variable names



53
54
55
56
57
58
59
60
# File 'lib/live_cable/rendering/method_analyzer.rb', line 53

def expanded_dependencies(method_name)
  analyze_all_methods unless analyzed

  @expanded_deps_cache ||= {}
  return @expanded_deps_cache[method_name] if @expanded_deps_cache.key?(method_name)

  @expanded_deps_cache[method_name] = compute_expanded_dependencies(method_name)
end