Class: Woods::Extractors::PhlexExtractor

Inherits:
Object
  • Object
show all
Includes:
RouteHelperResolver, SharedDependencyScanner, SharedUtilityMethods
Defined in:
lib/woods/extractors/phlex_extractor.rb

Overview

PhlexExtractor handles Phlex component extraction.

Phlex components are Ruby classes, making them more introspectable than ERB templates. We can extract:

  • Slot definitions (renders_one, renders_many)

  • Initialize parameters (the component’s API)

  • Component dependencies (what other components it renders)

  • Helper usage

  • Stimulus controller references

Examples:

extractor = PhlexExtractor.new
units = extractor.extract_all
card = units.find { |u| u.identifier == "Components::CardComponent" }

Constant Summary collapse

PHLEX_BASES =

Common Phlex base classes to look for

%w[
  Phlex::HTML
  Phlex::Component
  ApplicationComponent
].freeze

Constants included from RouteHelperResolver

RouteHelperResolver::IGNORED_HELPER_PREFIXES

Constants included from SharedDependencyScanner

SharedDependencyScanner::FORM_ACTION_HELPER, SharedDependencyScanner::ROUTE_HELPER_PATTERN

Instance Method Summary collapse

Methods included from RouteHelperResolver

#build_route_helper_map, #resolve_route_helper, #safe_rails_application_routes

Methods included from SharedDependencyScanner

#extract_constantize_targets, #scan_common_dependencies, #scan_form_dependencies, #scan_job_dependencies, #scan_mailer_dependencies, #scan_model_dependencies, #scan_navigation_dependencies, #scan_service_dependencies

Methods included from SharedUtilityMethods

#app_source?, #condition_label, #count_loc, #detect_entry_points, #extract_action_filter_actions, #extract_callback_conditions, #extract_class_methods, #extract_class_name, #extract_custom_errors, #extract_namespace, #extract_parent_class, #extract_public_methods, #resolve_source_location, #skip_file?

Constructor Details

#initializePhlexExtractor

Returns a new instance of PhlexExtractor.



36
37
38
39
40
41
42
# File 'lib/woods/extractors/phlex_extractor.rb', line 36

def initialize
  @component_base = find_component_base
  # Precompute the _path/_url → controller#action map once per
  # extraction run so navigation edges resolve to real targets
  # instead of the unresolved helper literal.
  build_route_helper_map
end

Instance Method Details

#extract_allArray<ExtractedUnit>

Extract all Phlex/ViewComponent components

Returns:



47
48
49
50
51
52
53
# File 'lib/woods/extractors/phlex_extractor.rb', line 47

def extract_all
  return [] unless @component_base

  @component_base.descendants.map do |component|
    extract_component(component)
  end.compact
end

#extract_component(component) ⇒ ExtractedUnit

Extract a single component

Parameters:

  • component (Class)

    The component class

Returns:



59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/woods/extractors/phlex_extractor.rb', line 59

def extract_component(component)
  return nil if component.name.nil?

  unit = ExtractedUnit.new(
    type: :component,
    identifier: component.name,
    file_path: source_file_for(component)
  )

  unit.namespace = extract_namespace(component)
  unit.source_code = read_source(unit.file_path)
  unit. = (component, unit.source_code)
  unit.dependencies = extract_dependencies(component, unit.source_code)

  unit
rescue StandardError => e
  Rails.logger.error("Failed to extract component #{component.name}: #{e.message}")
  nil
end