Class: Woods::Ast::MethodExtractor

Inherits:
Object
  • Object
show all
Includes:
SourceSpan
Defined in:
lib/woods/ast/method_extractor.rb

Overview

Extracts method definitions and their source from Ruby source code.

Replaces the fragile ~240 lines of ‘nesting_delta` / `neutralize_strings_and_comments` / `detect_heredoc_start` indentation heuristics in controller and mailer extractors.

Examples:

Extracting a method’s source

extractor = Ast::MethodExtractor.new
source = extractor.extract_method_source(code, "create")
# => "def create\n  @user = User.find(params[:id])\nend\n"

Instance Method Summary collapse

Constructor Details

#initialize(parser: nil) ⇒ MethodExtractor

Returns a new instance of MethodExtractor.

Parameters:

  • parser (Ast::Parser, nil) (defaults to: nil)

    Parser instance (creates default if nil)



22
23
24
# File 'lib/woods/ast/method_extractor.rb', line 22

def initialize(parser: nil)
  @parser = parser || Parser.new
end

Instance Method Details

#extract_all_methods(source) ⇒ Array<Ast::Node>

Extract all method definition nodes from source.

Parameters:

  • source (String)

    Ruby source code

Returns:

  • (Array<Ast::Node>)

    All :def and :defs nodes



45
46
47
48
# File 'lib/woods/ast/method_extractor.rb', line 45

def extract_all_methods(source)
  root = @parser.parse(source)
  root.find_all(:def) + root.find_all(:defs)
end

#extract_method(source, method_name, class_method: false) ⇒ Ast::Node?

Extract a method definition node by name.

Parameters:

  • source (String)

    Ruby source code

  • method_name (String)

    Method name to find

  • class_method (Boolean) (defaults to: false)

    If true, look for ‘def self.method_name`

Returns:

  • (Ast::Node, nil)

    The :def or :defs node, or nil if not found



32
33
34
35
36
37
38
39
# File 'lib/woods/ast/method_extractor.rb', line 32

def extract_method(source, method_name, class_method: false)
  root = @parser.parse(source)
  target_type = class_method ? :defs : :def

  root.find_all(target_type).find do |node|
    node.method_name == method_name.to_s
  end
end

#extract_method_source(source, method_name, class_method: false) ⇒ String?

Extract the raw source text of a method, including def…end.

This is the key replacement for ‘extract_action_source` in the controller and mailer extractors. Uses AST line tracking instead of indentation heuristics.

Parameters:

  • source (String)

    Ruby source code

  • method_name (String)

    Method name to find

  • class_method (Boolean) (defaults to: false)

    If true, look for ‘def self.method_name`

Returns:

  • (String, nil)

    The method source text, or nil if not found



59
60
61
62
63
64
65
66
67
68
# File 'lib/woods/ast/method_extractor.rb', line 59

def extract_method_source(source, method_name, class_method: false)
  node = extract_method(source, method_name, class_method: class_method)
  return nil unless node

  # If the node has a source field populated by the parser, use it
  return node.source if node.source

  # Fallback: extract by line range
  extract_source_span(source, node.line, node.end_line)
end