Module: ReferenceExtractor::Internal::NodeHelpers
- Defined in:
- lib/reference_extractor/internal/node_helpers.rb
Overview
Convenience methods for working with Parser::AST::Node nodes.
Defined Under Namespace
Classes: TypeError
Class Method Summary collapse
- .class?(node) ⇒ Boolean
- .class_or_module_name(class_or_module_node) ⇒ Object
- .constant?(node) ⇒ Boolean
- .constant_assignment?(node) ⇒ Boolean
- .constant_name(constant_node) ⇒ Object
- .each_child(node, &block) ⇒ Object
- .enclosing_namespace_path(starting_node, ancestors:) ⇒ Object
- .hash?(node) ⇒ Boolean
- .literal_value(string_or_symbol_node) ⇒ Object
- .location(node) ⇒ Object
- .method_arguments(method_call_node) ⇒ Object
- .method_call?(node) ⇒ Boolean
- .method_name(method_call_node) ⇒ Object
- .module_name_from_definition(node) ⇒ Object
- .name_location(node) ⇒ Object
- .parent_class(class_node) ⇒ Object
- .parent_module_name(ancestors:) ⇒ Object
- .string?(node) ⇒ Boolean
- .symbol?(node) ⇒ Boolean
- .value_from_hash(hash_node, key) ⇒ Object
Class Method Details
.class?(node) ⇒ Boolean
106 107 108 |
# File 'lib/reference_extractor/internal/node_helpers.rb', line 106 def class?(node) type_of(node) == CLASS end |
.class_or_module_name(class_or_module_node) ⇒ Object
13 14 15 16 17 18 19 20 21 22 23 24 25 |
# File 'lib/reference_extractor/internal/node_helpers.rb', line 13 def class_or_module_name(class_or_module_node) case type_of(class_or_module_node) when CLASS, MODULE # (class (const nil :Foo) (const nil :Bar) (nil)) # "class Foo < Bar; end" # (module (const nil :Foo) (nil)) # "module Foo; end" identifier = class_or_module_node.children[0] constant_name(identifier) else raise TypeError end end |
.constant?(node) ⇒ Boolean
98 99 100 |
# File 'lib/reference_extractor/internal/node_helpers.rb', line 98 def constant?(node) type_of(node) == CONSTANT end |
.constant_assignment?(node) ⇒ Boolean
102 103 104 |
# File 'lib/reference_extractor/internal/node_helpers.rb', line 102 def constant_assignment?(node) type_of(node) == CONSTANT_ASSIGNMENT end |
.constant_name(constant_node) ⇒ Object
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
# File 'lib/reference_extractor/internal/node_helpers.rb', line 27 def constant_name(constant_node) case type_of(constant_node) when CONSTANT_ROOT_NAMESPACE "" when CONSTANT, CONSTANT_ASSIGNMENT, SELF # (const nil :Foo) # "Foo" # (const (cbase) :Foo) # "::Foo" # (const (lvar :a) :Foo) # "a::Foo" # (casgn nil :Foo (int 1)) # "Foo = 1" # (casgn (cbase) :Foo (int 1)) # "::Foo = 1" # (casgn (lvar :a) :Foo (int 1)) # "a::Foo = 1" # (casgn (self) :Foo (int 1)) # "self::Foo = 1" namespace, name = constant_node.children if namespace [constant_name(namespace), name].join("::") else name.to_s end else raise TypeError end end |
.each_child(node, &block) ⇒ Object
58 59 60 61 62 63 64 65 66 |
# File 'lib/reference_extractor/internal/node_helpers.rb', line 58 def each_child(node, &block) if block node.children.each do |child| yield(child) if child.is_a?(Parser::AST::Node) end else enum_for(:each_child, node) end end |
.enclosing_namespace_path(starting_node, ancestors:) ⇒ Object
68 69 70 71 72 73 74 75 76 77 78 |
# File 'lib/reference_extractor/internal/node_helpers.rb', line 68 def enclosing_namespace_path(starting_node, ancestors:) ancestors.select { |n| [CLASS, MODULE].include?(type_of(n)) } .each_with_object([]) do |node, namespace| # when evaluating `class Child < Parent`, the const node for `Parent` is a child of the class # node, so it'll be an ancestor, but `Parent` is not evaluated in the namespace of `Child`, so # we need to skip it here next if type_of(node) == CLASS && parent_class(node) == starting_node namespace.prepend(class_or_module_name(node)) end end |
.hash?(node) ⇒ Boolean
114 115 116 |
# File 'lib/reference_extractor/internal/node_helpers.rb', line 114 def hash?(node) type_of(node) == HASH end |
.literal_value(string_or_symbol_node) ⇒ Object
80 81 82 83 84 85 86 87 88 89 90 91 |
# File 'lib/reference_extractor/internal/node_helpers.rb', line 80 def literal_value(string_or_symbol_node) case type_of(string_or_symbol_node) when STRING, SYMBOL # (str "foo") # "'foo'" # (sym :foo) # ":foo" string_or_symbol_node.children[0] else raise TypeError end end |
.location(node) ⇒ Object
93 94 95 96 |
# File 'lib/reference_extractor/internal/node_helpers.rb', line 93 def location(node) location = node.location Node::Location.new(location.line, location.column) end |
.method_arguments(method_call_node) ⇒ Object
126 127 128 129 130 131 132 |
# File 'lib/reference_extractor/internal/node_helpers.rb', line 126 def method_arguments(method_call_node) raise TypeError unless method_call?(method_call_node) # (send (lvar :foo) :bar (int 1)) # "foo.bar(1)" method_call_node.children.slice(2..-1) end |
.method_call?(node) ⇒ Boolean
110 111 112 |
# File 'lib/reference_extractor/internal/node_helpers.rb', line 110 def method_call?(node) type_of(node) == METHOD_CALL end |
.method_name(method_call_node) ⇒ Object
134 135 136 137 138 139 140 |
# File 'lib/reference_extractor/internal/node_helpers.rb', line 134 def method_name(method_call_node) raise TypeError unless method_call?(method_call_node) # (send (lvar :foo) :bar (int 1)) # "foo.bar(1)" method_call_node.children[1] end |
.module_name_from_definition(node) ⇒ Object
142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 |
# File 'lib/reference_extractor/internal/node_helpers.rb', line 142 def module_name_from_definition(node) case type_of(node) when CLASS, MODULE # "class My::Class; end" # "module My::Module; end" class_or_module_name(node) when CONSTANT_ASSIGNMENT # "My::Class = ..." # "My::Module = ..." rvalue = node.children.last case type_of(rvalue) when METHOD_CALL # "Class.new" # "Module.new" constant_name(node) if module_creation?(rvalue) when BLOCK # "Class.new do end" # "Module.new do end" constant_name(node) if module_creation?(method_call_node(rvalue)) end end end |
.name_location(node) ⇒ Object
166 167 168 169 170 171 172 173 |
# File 'lib/reference_extractor/internal/node_helpers.rb', line 166 def name_location(node) location = node.location if location.respond_to?(:name) name = location.name Node::Location.new(name.line, name.column) end end |
.parent_class(class_node) ⇒ Object
175 176 177 178 179 180 181 |
# File 'lib/reference_extractor/internal/node_helpers.rb', line 175 def parent_class(class_node) raise TypeError unless type_of(class_node) == CLASS # (class (const nil :Foo) (const nil :Bar) (nil)) # "class Foo < Bar; end" class_node.children[1] end |
.parent_module_name(ancestors:) ⇒ Object
183 184 185 186 187 188 189 190 191 192 |
# File 'lib/reference_extractor/internal/node_helpers.rb', line 183 def parent_module_name(ancestors:) definitions = ancestors .select { |n| [CLASS, MODULE, CONSTANT_ASSIGNMENT, BLOCK].include?(type_of(n)) } names = definitions.map do |definition| name_part_from_definition(definition) end.compact names.empty? ? "Object" : names.reverse.join("::") end |
.string?(node) ⇒ Boolean
118 119 120 |
# File 'lib/reference_extractor/internal/node_helpers.rb', line 118 def string?(node) type_of(node) == STRING end |
.symbol?(node) ⇒ Boolean
122 123 124 |
# File 'lib/reference_extractor/internal/node_helpers.rb', line 122 def symbol?(node) type_of(node) == SYMBOL end |
.value_from_hash(hash_node, key) ⇒ Object
194 195 196 197 198 199 |
# File 'lib/reference_extractor/internal/node_helpers.rb', line 194 def value_from_hash(hash_node, key) raise TypeError unless hash?(hash_node) pair = hash_pairs(hash_node).detect { |pair_node| literal_value(hash_pair_key(pair_node)) == key } hash_pair_value(pair) if pair end |