Class: AstTraverser

Inherits:
Object
  • Object
show all
Includes:
RuboCop::AST::Traversal
Defined in:
lib/tasks/helpers/ast_traverser.rb

Overview

:nodoc:

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeAstTraverser

Returns a new instance of AstTraverser.



12
13
14
# File 'lib/tasks/helpers/ast_traverser.rb', line 12

def initialize
  @stats = {}
end

Instance Attribute Details

#statsObject (readonly)

Returns the value of attribute stats.



10
11
12
# File 'lib/tasks/helpers/ast_traverser.rb', line 10

def stats
  @stats
end

Instance Method Details

#component_name(node) ⇒ Object



36
37
38
39
40
41
# File 'lib/tasks/helpers/ast_traverser.rb', line 36

def component_name(node)
  return node.receiver.const_name if node.method_name == :new

  helper_key = node.method_name.to_s.gsub("yattho_", "").to_sym
  Yattho::ViewHelper::HELPERS[helper_key]
end

#component_node?(node) ⇒ Boolean

Returns:

  • (Boolean)


32
33
34
# File 'lib/tasks/helpers/ast_traverser.rb', line 32

def component_node?(node)
  view_helpers.include?(node.method_name) || (node.method_name == :new && !node.receiver.nil? && ::Yattho::ViewComponents::STATUSES.key?(node.receiver.const_name))
end

#extract_arguments(node, name) ⇒ Object



43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/tasks/helpers/ast_traverser.rb', line 43

def extract_arguments(node, name)
  args = node.arguments
  res = {}

  return res if args.empty?

  kwargs = args.last
  if kwargs.respond_to?(:pairs)
    res = kwargs.pairs.each_with_object({}) do |pair, h|
      h.merge!(extract_values(pair))
    end
  end

  # Octicon is the only component that accepts positional arguments.
  res[:icon] = args.first.source if name == "Yattho::Beta::Octicon" && args.size > 1

  res
end

#extract_values(pair) ⇒ Object



62
63
64
65
66
# File 'lib/tasks/helpers/ast_traverser.rb', line 62

def extract_values(pair)
  return { pair.key.value => pair.value.source } unless pair.value.type == :hash

  flatten_pairs(pair, prefix: "#{pair.key.value}-")
end

#flatten_pairs(pair, prefix: "") ⇒ Object



68
69
70
71
72
73
74
75
76
# File 'lib/tasks/helpers/ast_traverser.rb', line 68

def flatten_pairs(pair, prefix: "")
  pair.value.pairs.each_with_object({}) do |value_pair, h|
    if value_pair.value.type == :hash
      h.merge!(flatten_pairs(value_pair, prefix: "#{prefix}#{value_pair.key.value}-"))
    else
      h.merge!("#{prefix}#{value_pair.key.value}" => value_pair.value.source)
    end
  end
end

#on_send(node) ⇒ Object



16
17
18
19
20
21
22
23
24
25
26
# File 'lib/tasks/helpers/ast_traverser.rb', line 16

def on_send(node)
  return super(node) unless component_node?(node)

  name = component_name(node)
  args = extract_arguments(node, name)

  @stats[name] = { path: node.loc.expression.source_buffer.name }
  @stats[name][:arguments] = args unless args.empty?

  super(node) # recursively iterate over children
end

#view_helpersObject



28
29
30
# File 'lib/tasks/helpers/ast_traverser.rb', line 28

def view_helpers
  @view_helpers ||= ::Yattho::ViewHelper::HELPERS.keys.map { |key| "yattho_#{key}".to_sym }
end