jonatas / fast

Find in AST - Search and refactor code directly in Abstract Syntax Tree as you do with grep for strings

Home Page:https://jonatas.github.io/fast/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Methods with = in names

zverok opened this issue · comments

First of all, thanks for the amazing library!

I have a problem with this syntax:

require 'fast'

a = Fast.ast('
class A
  self.abstract_class = true
end')
pp Fast.search([:send, :self, :abstract_class=, :true], a) 
# => [s(:send, s(:self), :abstract_class=, s(:true))]
pp Fast.search('(send self abstract_class= true)', a) 
# => []

According to Fast.debug { }, it tries to search for abstract_class symbol, withot =. I can't find any suggetion about screening/escaping the character.

Thanks!

(BTW, if it is not possible currently to use strings for searching writer methods, I'd be happy for a suggestion how to specify captures in "array-of-symbols" syntax, just naive '$_' seems ot to work.)

Hello @zverok ! thanks for sharing the case. I'll need to provide this in the parser. I'll be working on it soon.

For now, you can expose it as external arguments:

[4] pry(main)> Fast.search('(send self %1 true)', a, :abstract_class=)
=> [s(:send,
  s(:self), :abstract_class=,
  s(:true))]

But we still have to make it official because I missed passing the extra args to search
method:

⋊> ~/c/fast on master ⨯ git diff                                                                                                                                                                                                                                    
diff --git lib/fast.rb lib/fast.rb
index e48d80a..0c4e2f0 100644
--- lib/fast.rb
+++ lib/fast.rb
@@ -168,13 +168,13 @@ module Fast
     # If the node matches with the pattern it returns the node,
     # otherwise it recursively collect possible children nodes
     # @yield node and capture if block given
-    def search(pattern, node)
-      if (match = match?(pattern, node))
+    def search(pattern, node, *args)
+      if (match = match?(pattern, node, *args))
         yield node, match if block_given?
         match != true ? [node, match] : [node]
       else
         node.each_child_node
-          .flat_map { |child| search(pattern, child) }
+          .flat_map { |child| search(pattern, child, *args) }
           .compact.flatten
       end

I'll also include the = from setters to be allowed in the ExpressionParser.

@zverok I released version 0.1.8 with the fix :)

Thanks, it works! 👍